/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/backtrace.rs
Line
Count
Source (jump to first uncovered line)
1
#[cfg(std_backtrace)]
2
pub(crate) use std::backtrace::{Backtrace, BacktraceStatus};
3
4
#[cfg(all(not(std_backtrace), feature = "backtrace"))]
5
pub(crate) use self::capture::{Backtrace, BacktraceStatus};
6
7
#[cfg(not(any(std_backtrace, feature = "backtrace")))]
8
pub(crate) enum Backtrace {}
9
10
#[cfg(std_backtrace)]
11
macro_rules! impl_backtrace {
12
    () => {
13
        std::backtrace::Backtrace
14
    };
15
}
16
17
#[cfg(all(not(std_backtrace), feature = "backtrace"))]
18
macro_rules! impl_backtrace {
19
    () => {
20
        impl core::fmt::Debug + core::fmt::Display
21
    };
22
}
23
24
#[cfg(any(std_backtrace, feature = "backtrace"))]
25
macro_rules! backtrace {
26
    () => {
27
        Some(crate::backtrace::Backtrace::capture())
28
    };
29
}
30
31
#[cfg(not(any(std_backtrace, feature = "backtrace")))]
32
macro_rules! backtrace {
33
    () => {
34
        None
35
    };
36
}
37
38
#[cfg(error_generic_member_access)]
39
macro_rules! backtrace_if_absent {
40
    ($err:expr) => {
41
        match std::error::request_ref::<std::backtrace::Backtrace>($err as &dyn std::error::Error) {
42
            Some(_) => None,
43
            None => backtrace!(),
44
        }
45
    };
46
}
47
48
#[cfg(all(
49
    feature = "std",
50
    not(error_generic_member_access),
51
    any(std_backtrace, feature = "backtrace")
52
))]
53
macro_rules! backtrace_if_absent {
54
    ($err:expr) => {
55
        backtrace!()
56
    };
57
}
58
59
#[cfg(all(feature = "std", not(std_backtrace), not(feature = "backtrace")))]
60
macro_rules! backtrace_if_absent {
61
    ($err:expr) => {
62
        None
63
    };
64
}
65
66
#[cfg(all(not(std_backtrace), feature = "backtrace"))]
67
mod capture {
68
    use alloc::borrow::{Cow, ToOwned as _};
69
    use alloc::vec::Vec;
70
    use backtrace::{BacktraceFmt, BytesOrWideString, Frame, PrintFmt, SymbolName};
71
    use core::cell::UnsafeCell;
72
    use core::fmt::{self, Debug, Display};
73
    use core::sync::atomic::{AtomicUsize, Ordering};
74
    use std::env;
75
    use std::path::{self, Path, PathBuf};
76
    use std::sync::Once;
77
78
    pub(crate) struct Backtrace {
79
        inner: Inner,
80
    }
81
82
    pub(crate) enum BacktraceStatus {
83
        Unsupported,
84
        Disabled,
85
        Captured,
86
    }
87
88
    enum Inner {
89
        Unsupported,
90
        Disabled,
91
        Captured(LazilyResolvedCapture),
92
    }
93
94
    struct Capture {
95
        actual_start: usize,
96
        resolved: bool,
97
        frames: Vec<BacktraceFrame>,
98
    }
99
100
    struct BacktraceFrame {
101
        frame: Frame,
102
        symbols: Vec<BacktraceSymbol>,
103
    }
104
105
    struct BacktraceSymbol {
106
        name: Option<Vec<u8>>,
107
        filename: Option<BytesOrWide>,
108
        lineno: Option<u32>,
109
        colno: Option<u32>,
110
    }
111
112
    enum BytesOrWide {
113
        Bytes(Vec<u8>),
114
        Wide(Vec<u16>),
115
    }
116
117
    impl Debug for Backtrace {
118
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
119
            let capture = match &self.inner {
120
                Inner::Unsupported => return fmt.write_str("<unsupported>"),
121
                Inner::Disabled => return fmt.write_str("<disabled>"),
122
                Inner::Captured(c) => c.force(),
123
            };
124
125
            let frames = &capture.frames[capture.actual_start..];
126
127
            write!(fmt, "Backtrace ")?;
128
129
            let mut dbg = fmt.debug_list();
130
131
            for frame in frames {
132
                if frame.frame.ip().is_null() {
133
                    continue;
134
                }
135
136
                dbg.entries(&frame.symbols);
137
            }
138
139
            dbg.finish()
140
        }
141
    }
142
143
    impl Debug for BacktraceFrame {
144
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
145
            let mut dbg = fmt.debug_list();
146
            dbg.entries(&self.symbols);
147
            dbg.finish()
148
        }
149
    }
150
151
    impl Debug for BacktraceSymbol {
152
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
153
            write!(fmt, "{{ ")?;
154
155
            if let Some(fn_name) = self.name.as_ref().map(|b| SymbolName::new(b)) {
156
                write!(fmt, "fn: \"{:#}\"", fn_name)?;
157
            } else {
158
                write!(fmt, "fn: <unknown>")?;
159
            }
160
161
            if let Some(fname) = self.filename.as_ref() {
162
                write!(fmt, ", file: \"{:?}\"", fname)?;
163
            }
164
165
            if let Some(line) = self.lineno {
166
                write!(fmt, ", line: {:?}", line)?;
167
            }
168
169
            write!(fmt, " }}")
170
        }
171
    }
172
173
    impl Debug for BytesOrWide {
174
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
175
            output_filename(
176
                fmt,
177
                match self {
178
                    BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
179
                    BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
180
                },
181
                PrintFmt::Short,
182
                env::current_dir().as_ref().ok(),
183
            )
184
        }
185
    }
186
187
    impl Backtrace {
188
        fn enabled() -> bool {
189
            static ENABLED: AtomicUsize = AtomicUsize::new(0);
190
            match ENABLED.load(Ordering::Relaxed) {
191
                0 => {}
192
                1 => return false,
193
                _ => return true,
194
            }
195
            let enabled = match env::var_os("RUST_LIB_BACKTRACE") {
196
                Some(s) => s != "0",
197
                None => match env::var_os("RUST_BACKTRACE") {
198
                    Some(s) => s != "0",
199
                    None => false,
200
                },
201
            };
202
            ENABLED.store(enabled as usize + 1, Ordering::Relaxed);
203
            enabled
204
        }
205
206
        #[inline(never)] // want to make sure there's a frame here to remove
207
        pub(crate) fn capture() -> Backtrace {
208
            if Backtrace::enabled() {
209
                Backtrace::create(Backtrace::capture as usize)
210
            } else {
211
                let inner = Inner::Disabled;
212
                Backtrace { inner }
213
            }
214
        }
215
216
        // Capture a backtrace which starts just before the function addressed
217
        // by `ip`
218
        fn create(ip: usize) -> Backtrace {
219
            let mut frames = Vec::new();
220
            let mut actual_start = None;
221
            backtrace::trace(|frame| {
222
                frames.push(BacktraceFrame {
223
                    frame: frame.clone(),
224
                    symbols: Vec::new(),
225
                });
226
                if frame.symbol_address() as usize == ip && actual_start.is_none() {
227
                    actual_start = Some(frames.len() + 1);
228
                }
229
                true
230
            });
231
232
            // If no frames came out assume that this is an unsupported platform
233
            // since `backtrace` doesn't provide a way of learning this right
234
            // now, and this should be a good enough approximation.
235
            let inner = if frames.is_empty() {
236
                Inner::Unsupported
237
            } else {
238
                Inner::Captured(LazilyResolvedCapture::new(Capture {
239
                    actual_start: actual_start.unwrap_or(0),
240
                    frames,
241
                    resolved: false,
242
                }))
243
            };
244
245
            Backtrace { inner }
246
        }
247
248
        pub(crate) fn status(&self) -> BacktraceStatus {
249
            match self.inner {
250
                Inner::Unsupported => BacktraceStatus::Unsupported,
251
                Inner::Disabled => BacktraceStatus::Disabled,
252
                Inner::Captured(_) => BacktraceStatus::Captured,
253
            }
254
        }
255
    }
256
257
    impl Display for Backtrace {
258
        fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
259
            let capture = match &self.inner {
260
                Inner::Unsupported => return fmt.write_str("unsupported backtrace"),
261
                Inner::Disabled => return fmt.write_str("disabled backtrace"),
262
                Inner::Captured(c) => c.force(),
263
            };
264
265
            let full = fmt.alternate();
266
            let (frames, style) = if full {
267
                (&capture.frames[..], PrintFmt::Full)
268
            } else {
269
                (&capture.frames[capture.actual_start..], PrintFmt::Short)
270
            };
271
272
            // When printing paths we try to strip the cwd if it exists,
273
            // otherwise we just print the path as-is. Note that we also only do
274
            // this for the short format, because if it's full we presumably
275
            // want to print everything.
276
            let cwd = env::current_dir();
277
            let mut print_path = move |fmt: &mut fmt::Formatter, path: BytesOrWideString| {
278
                output_filename(fmt, path, style, cwd.as_ref().ok())
279
            };
280
281
            let mut f = BacktraceFmt::new(fmt, style, &mut print_path);
282
            f.add_context()?;
283
            for frame in frames {
284
                let mut f = f.frame();
285
                if frame.symbols.is_empty() {
286
                    f.print_raw(frame.frame.ip(), None, None, None)?;
287
                } else {
288
                    for symbol in frame.symbols.iter() {
289
                        f.print_raw_with_column(
290
                            frame.frame.ip(),
291
                            symbol.name.as_ref().map(|b| SymbolName::new(b)),
292
                            symbol.filename.as_ref().map(|b| match b {
293
                                BytesOrWide::Bytes(w) => BytesOrWideString::Bytes(w),
294
                                BytesOrWide::Wide(w) => BytesOrWideString::Wide(w),
295
                            }),
296
                            symbol.lineno,
297
                            symbol.colno,
298
                        )?;
299
                    }
300
                }
301
            }
302
            f.finish()?;
303
            Ok(())
304
        }
305
    }
306
307
    struct LazilyResolvedCapture {
308
        sync: Once,
309
        capture: UnsafeCell<Capture>,
310
    }
311
312
    impl LazilyResolvedCapture {
313
        fn new(capture: Capture) -> Self {
314
            LazilyResolvedCapture {
315
                sync: Once::new(),
316
                capture: UnsafeCell::new(capture),
317
            }
318
        }
319
320
        fn force(&self) -> &Capture {
321
            self.sync.call_once(|| {
322
                // Safety: This exclusive reference can't overlap with any
323
                // others. `Once` guarantees callers will block until this
324
                // closure returns. `Once` also guarantees only a single caller
325
                // will enter this closure.
326
                unsafe { &mut *self.capture.get() }.resolve();
327
            });
328
329
            // Safety: This shared reference can't overlap with the exclusive
330
            // reference above.
331
            unsafe { &*self.capture.get() }
332
        }
333
    }
334
335
    // Safety: Access to the inner value is synchronized using a thread-safe
336
    // `Once`. So long as `Capture` is `Sync`, `LazilyResolvedCapture` is too
337
    unsafe impl Sync for LazilyResolvedCapture where Capture: Sync {}
338
339
    impl Capture {
340
        fn resolve(&mut self) {
341
            // If we're already resolved, nothing to do!
342
            if self.resolved {
343
                return;
344
            }
345
            self.resolved = true;
346
347
            for frame in self.frames.iter_mut() {
348
                let symbols = &mut frame.symbols;
349
                let frame = &frame.frame;
350
                backtrace::resolve_frame(frame, |symbol| {
351
                    symbols.push(BacktraceSymbol {
352
                        name: symbol.name().map(|m| m.as_bytes().to_vec()),
353
                        filename: symbol.filename_raw().map(|b| match b {
354
                            BytesOrWideString::Bytes(b) => BytesOrWide::Bytes(b.to_owned()),
355
                            BytesOrWideString::Wide(b) => BytesOrWide::Wide(b.to_owned()),
356
                        }),
357
                        lineno: symbol.lineno(),
358
                        colno: symbol.colno(),
359
                    });
360
                });
361
            }
362
        }
363
    }
364
365
    // Prints the filename of the backtrace frame.
366
    fn output_filename(
367
        fmt: &mut fmt::Formatter,
368
        bows: BytesOrWideString,
369
        print_fmt: PrintFmt,
370
        cwd: Option<&PathBuf>,
371
    ) -> fmt::Result {
372
        let file: Cow<Path> = match bows {
373
            #[cfg(unix)]
374
            BytesOrWideString::Bytes(bytes) => {
375
                use std::os::unix::ffi::OsStrExt;
376
                Path::new(std::ffi::OsStr::from_bytes(bytes)).into()
377
            }
378
            #[cfg(not(unix))]
379
            BytesOrWideString::Bytes(bytes) => {
380
                Path::new(std::str::from_utf8(bytes).unwrap_or("<unknown>")).into()
381
            }
382
            #[cfg(windows)]
383
            BytesOrWideString::Wide(wide) => {
384
                use std::os::windows::ffi::OsStringExt;
385
                Cow::Owned(std::ffi::OsString::from_wide(wide).into())
386
            }
387
            #[cfg(not(windows))]
388
            BytesOrWideString::Wide(_wide) => Path::new("<unknown>").into(),
389
        };
390
        if print_fmt == PrintFmt::Short && file.is_absolute() {
391
            if let Some(cwd) = cwd {
392
                if let Ok(stripped) = file.strip_prefix(&cwd) {
393
                    if let Some(s) = stripped.to_str() {
394
                        return write!(fmt, ".{}{}", path::MAIN_SEPARATOR, s);
395
                    }
396
                }
397
            }
398
        }
399
        Display::fmt(&file.display(), fmt)
400
    }
401
}
402
403
0
fn _assert_send_sync() {
404
0
    fn _assert<T: Send + Sync>() {}
405
0
    _assert::<Backtrace>();
406
0
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/chain.rs
Line
Count
Source (jump to first uncovered line)
1
use self::ChainState::*;
2
use crate::StdError;
3
4
#[cfg(feature = "std")]
5
use alloc::vec::{self, Vec};
6
7
#[cfg(feature = "std")]
8
pub(crate) use crate::Chain;
9
10
#[cfg(not(feature = "std"))]
11
pub(crate) struct Chain<'a> {
12
    state: ChainState<'a>,
13
}
14
15
#[derive(Clone)]
16
pub(crate) enum ChainState<'a> {
17
    Linked {
18
        next: Option<&'a (dyn StdError + 'static)>,
19
    },
20
    #[cfg(feature = "std")]
21
    Buffered {
22
        rest: vec::IntoIter<&'a (dyn StdError + 'static)>,
23
    },
24
}
25
26
impl<'a> Chain<'a> {
27
    #[cold]
28
0
    pub fn new(head: &'a (dyn StdError + 'static)) -> Self {
29
0
        Chain {
30
0
            state: ChainState::Linked { next: Some(head) },
31
0
        }
32
0
    }
33
}
34
35
impl<'a> Iterator for Chain<'a> {
36
    type Item = &'a (dyn StdError + 'static);
37
38
0
    fn next(&mut self) -> Option<Self::Item> {
39
0
        match &mut self.state {
40
0
            Linked { next } => {
41
0
                let error = (*next)?;
42
0
                *next = error.source();
43
0
                Some(error)
44
            }
45
            #[cfg(feature = "std")]
46
0
            Buffered { rest } => rest.next(),
47
        }
48
0
    }
49
50
0
    fn size_hint(&self) -> (usize, Option<usize>) {
51
0
        let len = self.len();
52
0
        (len, Some(len))
53
0
    }
54
}
55
56
#[cfg(feature = "std")]
57
impl DoubleEndedIterator for Chain<'_> {
58
0
    fn next_back(&mut self) -> Option<Self::Item> {
59
0
        match &mut self.state {
60
0
            Linked { mut next } => {
61
0
                let mut rest = Vec::new();
62
0
                while let Some(cause) = next {
63
0
                    next = cause.source();
64
0
                    rest.push(cause);
65
0
                }
66
0
                let mut rest = rest.into_iter();
67
0
                let last = rest.next_back();
68
0
                self.state = Buffered { rest };
69
0
                last
70
            }
71
0
            Buffered { rest } => rest.next_back(),
72
        }
73
0
    }
74
}
75
76
impl ExactSizeIterator for Chain<'_> {
77
0
    fn len(&self) -> usize {
78
0
        match &self.state {
79
0
            Linked { mut next } => {
80
0
                let mut len = 0;
81
0
                while let Some(cause) = next {
82
0
                    next = cause.source();
83
0
                    len += 1;
84
0
                }
85
0
                len
86
            }
87
            #[cfg(feature = "std")]
88
0
            Buffered { rest } => rest.len(),
89
        }
90
0
    }
91
}
92
93
#[cfg(feature = "std")]
94
impl Default for Chain<'_> {
95
0
    fn default() -> Self {
96
0
        Chain {
97
0
            state: ChainState::Buffered {
98
0
                rest: Vec::new().into_iter(),
99
0
            },
100
0
        }
101
0
    }
102
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/context.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::error::ContextError;
2
use crate::{Context, Error, StdError};
3
use core::convert::Infallible;
4
use core::fmt::{self, Debug, Display, Write};
5
6
#[cfg(error_generic_member_access)]
7
use std::error::Request;
8
9
mod ext {
10
    use super::*;
11
12
    pub trait StdError {
13
        fn ext_context<C>(self, context: C) -> Error
14
        where
15
            C: Display + Send + Sync + 'static;
16
    }
17
18
    #[cfg(feature = "std")]
19
    impl<E> StdError for E
20
    where
21
        E: std::error::Error + Send + Sync + 'static,
22
    {
23
0
        fn ext_context<C>(self, context: C) -> Error
24
0
        where
25
0
            C: Display + Send + Sync + 'static,
26
0
        {
27
0
            let backtrace = backtrace_if_absent!(&self);
28
0
            Error::from_context(context, self, backtrace)
29
0
        }
30
    }
31
32
    impl StdError for Error {
33
0
        fn ext_context<C>(self, context: C) -> Error
34
0
        where
35
0
            C: Display + Send + Sync + 'static,
36
0
        {
37
0
            self.context(context)
38
0
        }
Unexecuted instantiation: _RINvXs_NtNtCskkyJyiFoyZJ_6anyhow7context3extNtB9_5ErrorNtB5_8StdError11ext_contextReECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvXs_NtNtCskkyJyiFoyZJ_6anyhow7context3extNtB9_5ErrorNtB5_8StdError11ext_contextpEB9_
39
    }
40
}
41
42
impl<T, E> Context<T, E> for Result<T, E>
43
where
44
    E: ext::StdError + Send + Sync + 'static,
45
{
46
86.9k
    fn context<C>(self, context: C) -> Result<T, Error>
47
86.9k
    where
48
86.9k
        C: Display + Send + Sync + 'static,
49
86.9k
    {
50
86.9k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
86.9k
        // in ext_context.
52
86.9k
        match self {
53
86.9k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
86.9k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtBD_6option6OptionmENtB5_5ErrorEINtB5_7ContextB1a_B1y_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
582
    fn context<C>(self, context: C) -> Result<T, Error>
47
582
    where
48
582
        C: Display + Send + Sync + 'static,
49
582
    {
50
582
        // Not using map_err to save 2 useless frames off the captured backtrace
51
582
        // in ext_context.
52
582
        match self {
53
582
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
582
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types10MemoryTypeENtB5_5ErrorEINtB5_7ContextB1a_B2O_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
1.41k
    fn context<C>(self, context: C) -> Result<T, Error>
47
1.41k
    where
48
1.41k
        C: Display + Send + Sync + 'static,
49
1.41k
    {
50
1.41k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
1.41k
        // in ext_context.
52
1.41k
        match self {
53
1.41k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
1.41k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types4DataENtB5_5ErrorEINtB5_7ContextB1a_B2H_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
176
    fn context<C>(self, context: C) -> Result<T, Error>
47
176
    where
48
176
        C: Display + Send + Sync + 'static,
49
176
    {
50
176
        // Not using map_err to save 2 useless frames off the captured backtrace
51
176
        // in ext_context.
52
176
        match self {
53
176
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
176
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types6ExportENtB5_5ErrorEINtB5_7ContextB1a_B2J_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
897
    fn context<C>(self, context: C) -> Result<T, Error>
47
897
    where
48
897
        C: Display + Send + Sync + 'static,
49
897
    {
50
897
        // Not using map_err to save 2 useless frames off the captured backtrace
51
897
        // in ext_context.
52
897
        match self {
53
897
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
897
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types6GlobalENtB5_5ErrorEINtB5_7ContextB1a_B2J_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
1.67k
    fn context<C>(self, context: C) -> Result<T, Error>
47
1.67k
    where
48
1.67k
        C: Display + Send + Sync + 'static,
49
1.67k
    {
50
1.67k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
1.67k
        // in ext_context.
52
1.67k
        match self {
53
1.67k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
1.67k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types6ImportENtB5_5ErrorEINtB5_7ContextB1a_B2J_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
2.55k
    fn context<C>(self, context: C) -> Result<T, Error>
47
2.55k
    where
48
2.55k
        C: Display + Send + Sync + 'static,
49
2.55k
    {
50
2.55k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
2.55k
        // in ext_context.
52
2.55k
        match self {
53
2.55k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
2.55k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types7ElementENtB5_5ErrorEINtB5_7ContextB1a_B2K_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
252
    fn context<C>(self, context: C) -> Result<T, Error>
47
252
    where
48
252
        C: Display + Send + Sync + 'static,
49
252
    {
50
252
        // Not using map_err to save 2 useless frames off the captured backtrace
51
252
        // in ext_context.
52
252
        match self {
53
252
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
252
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types8FuncTypeENtB5_5ErrorEINtB5_7ContextB1a_B2L_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
9.26k
    fn context<C>(self, context: C) -> Result<T, Error>
47
9.26k
    where
48
9.26k
        C: Display + Send + Sync + 'static,
49
9.26k
    {
50
9.26k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
9.26k
        // in ext_context.
52
9.26k
        match self {
53
9.26k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
9.26k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types9TableTypeENtB5_5ErrorEINtB5_7ContextB1a_B2M_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
1.03k
    fn context<C>(self, context: C) -> Result<T, Error>
47
1.03k
    where
48
1.03k
        C: Display + Send + Sync + 'static,
49
1.03k
    {
50
1.03k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
1.03k
        // in ext_context.
52
1.03k
        match self {
53
1.03k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
1.03k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary5types9ValueTypeENtB5_5ErrorEINtB5_7ContextB1a_B2M_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
11.3k
    fn context<C>(self, context: C) -> Result<T, Error>
47
11.3k
    where
48
11.3k
        C: Display + Send + Sync + 'static,
49
11.3k
    {
50
11.3k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
11.3k
        // in ext_context.
52
11.3k
        match self {
53
11.3k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
11.3k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary7section4code4CodeENtB5_5ErrorEINtB5_7ContextB1a_B2Q_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
4.09k
    fn context<C>(self, context: C) -> Result<T, Error>
47
4.09k
    where
48
4.09k
        C: Display + Send + Sync + 'static,
49
4.09k
    {
50
4.09k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
4.09k
        // in ext_context.
52
4.09k
        match self {
53
4.09k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
4.09k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtCsbpSlAbJY2yh_5alloc3vec3VecmENtB5_5ErrorEINtB5_7ContextB1a_B1J_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
4.09k
    fn context<C>(self, context: C) -> Result<T, Error>
47
4.09k
    where
48
4.09k
        C: Display + Send + Sync + 'static,
49
4.09k
    {
50
4.09k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
4.09k
        // in ext_context.
52
4.09k
        match self {
53
4.09k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
4.09k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultNtNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary12instructions5block9BlockTypeNtB5_5ErrorEINtB5_7ContextB1a_B2u_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
6.68k
    fn context<C>(self, context: C) -> Result<T, Error>
47
6.68k
    where
48
6.68k
        C: Display + Send + Sync + 'static,
49
6.68k
    {
50
6.68k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
6.68k
        // in ext_context.
52
6.68k
        match self {
53
6.68k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
6.68k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResulthNtB5_5ErrorEINtB5_7ContexthB1b_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
21.4k
    fn context<C>(self, context: C) -> Result<T, Error>
47
21.4k
    where
48
21.4k
        C: Display + Send + Sync + 'static,
49
21.4k
    {
50
21.4k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
21.4k
        // in ext_context.
52
21.4k
        match self {
53
21.4k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
21.4k
    }
_RINvXNtCskkyJyiFoyZJ_6anyhow7contextINtNtCs1ujR1JRCAmI_4core6result6ResultmNtB5_5ErrorEINtB5_7ContextmB1b_E7contextReECs5HNiFFfDLPG_6decode
Line
Count
Source
46
21.4k
    fn context<C>(self, context: C) -> Result<T, Error>
47
21.4k
    where
48
21.4k
        C: Display + Send + Sync + 'static,
49
21.4k
    {
50
21.4k
        // Not using map_err to save 2 useless frames off the captured backtrace
51
21.4k
        // in ext_context.
52
21.4k
        match self {
53
21.4k
            Ok(ok) => Ok(ok),
54
0
            Err(error) => Err(error.ext_context(context)),
55
        }
56
21.4k
    }
Unexecuted instantiation: _RINvXININtCskkyJyiFoyZJ_6anyhow7context0ppEINtNtCs1ujR1JRCAmI_4core6result6ResultppEINtB8_7ContextppE7contextpEB8_
57
58
0
    fn with_context<C, F>(self, context: F) -> Result<T, Error>
59
0
    where
60
0
        C: Display + Send + Sync + 'static,
61
0
        F: FnOnce() -> C,
62
0
    {
63
0
        match self {
64
0
            Ok(ok) => Ok(ok),
65
0
            Err(error) => Err(error.ext_context(context())),
66
        }
67
0
    }
68
}
69
70
/// ```
71
/// # type T = ();
72
/// #
73
/// use anyhow::{Context, Result};
74
///
75
/// fn maybe_get() -> Option<T> {
76
///     # const IGNORE: &str = stringify! {
77
///     ...
78
///     # };
79
///     # unimplemented!()
80
/// }
81
///
82
/// fn demo() -> Result<()> {
83
///     let t = maybe_get().context("there is no T")?;
84
///     # const IGNORE: &str = stringify! {
85
///     ...
86
///     # };
87
///     # unimplemented!()
88
/// }
89
/// ```
90
impl<T> Context<T, Infallible> for Option<T> {
91
0
    fn context<C>(self, context: C) -> Result<T, Error>
92
0
    where
93
0
        C: Display + Send + Sync + 'static,
94
0
    {
95
0
        // Not using ok_or_else to save 2 useless frames off the captured
96
0
        // backtrace.
97
0
        match self {
98
0
            Some(ok) => Ok(ok),
99
0
            None => Err(Error::from_display(context, backtrace!())),
100
        }
101
0
    }
102
103
0
    fn with_context<C, F>(self, context: F) -> Result<T, Error>
104
0
    where
105
0
        C: Display + Send + Sync + 'static,
106
0
        F: FnOnce() -> C,
107
0
    {
108
0
        match self {
109
0
            Some(ok) => Ok(ok),
110
0
            None => Err(Error::from_display(context(), backtrace!())),
111
        }
112
0
    }
113
}
114
115
impl<C, E> Debug for ContextError<C, E>
116
where
117
    C: Display,
118
    E: Debug,
119
{
120
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
121
0
        f.debug_struct("Error")
122
0
            .field("context", &Quoted(&self.context))
123
0
            .field("source", &self.error)
124
0
            .finish()
125
0
    }
Unexecuted instantiation: _RNvXs0_NtCskkyJyiFoyZJ_6anyhow7contextINtNtB7_5error12ContextErrorReNtB7_5ErrorENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXININtCskkyJyiFoyZJ_6anyhow7contexts0_0ppEINtNtB7_5error12ContextErrorppENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtB7_
126
}
127
128
impl<C, E> Display for ContextError<C, E>
129
where
130
    C: Display,
131
{
132
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
133
0
        Display::fmt(&self.context, f)
134
0
    }
Unexecuted instantiation: _RNvXs1_NtCskkyJyiFoyZJ_6anyhow7contextINtNtB7_5error12ContextErrorReNtB7_5ErrorENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXININtCskkyJyiFoyZJ_6anyhow7contexts1_0ppEINtNtB7_5error12ContextErrorppENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtB7_
135
}
136
137
impl<C, E> StdError for ContextError<C, E>
138
where
139
    C: Display,
140
    E: StdError + 'static,
141
{
142
0
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
143
0
        Some(&self.error)
144
0
    }
145
146
    #[cfg(error_generic_member_access)]
147
0
    fn provide<'a>(&'a self, request: &mut Request<'a>) {
148
0
        StdError::provide(&self.error, request);
149
0
    }
150
}
151
152
impl<C> StdError for ContextError<C, Error>
153
where
154
    C: Display,
155
{
156
0
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
157
0
        Some(unsafe { crate::ErrorImpl::error(self.error.inner.by_ref()) })
158
0
    }
Unexecuted instantiation: _RNvXs3_NtCskkyJyiFoyZJ_6anyhow7contextINtNtB7_5error12ContextErrorReNtB7_5ErrorENtNtCs1ujR1JRCAmI_4core5error5Error6sourceCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXININtCskkyJyiFoyZJ_6anyhow7contexts3_0pEINtNtB7_5error12ContextErrorpNtB7_5ErrorENtNtCs1ujR1JRCAmI_4core5error5Error6sourceB7_
159
160
    #[cfg(error_generic_member_access)]
161
0
    fn provide<'a>(&'a self, request: &mut Request<'a>) {
162
0
        Error::provide(&self.error, request);
163
0
    }
Unexecuted instantiation: _RNvXs3_NtCskkyJyiFoyZJ_6anyhow7contextINtNtB7_5error12ContextErrorReNtB7_5ErrorENtNtCs1ujR1JRCAmI_4core5error5Error7provideCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXININtCskkyJyiFoyZJ_6anyhow7contexts3_0pEINtNtB7_5error12ContextErrorpNtB7_5ErrorENtNtCs1ujR1JRCAmI_4core5error5Error7provideB7_
164
}
165
166
struct Quoted<C>(C);
167
168
impl<C> Debug for Quoted<C>
169
where
170
    C: Display,
171
{
172
0
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
173
0
        formatter.write_char('"')?;
174
0
        Quoted(&mut *formatter).write_fmt(format_args!("{}", self.0))?;
175
0
        formatter.write_char('"')?;
176
0
        Ok(())
177
0
    }
Unexecuted instantiation: _RNvXs4_NtCskkyJyiFoyZJ_6anyhow7contextINtB5_6QuotedRReENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXININtCskkyJyiFoyZJ_6anyhow7contexts4_0pEINtB5_6QuotedpENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtB7_
178
}
179
180
impl Write for Quoted<&mut fmt::Formatter<'_>> {
181
0
    fn write_str(&mut self, s: &str) -> fmt::Result {
182
0
        Display::fmt(&s.escape_debug(), self.0)
183
0
    }
184
}
185
186
pub(crate) mod private {
187
    use super::*;
188
189
    pub trait Sealed {}
190
191
    impl<T, E> Sealed for Result<T, E> where E: ext::StdError {}
192
    impl<T> Sealed for Option<T> {}
193
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/ensure.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::Error;
2
use alloc::string::String;
3
use core::fmt::{self, Debug, Write};
4
use core::mem::MaybeUninit;
5
use core::ptr;
6
use core::slice;
7
use core::str;
8
9
#[doc(hidden)]
10
pub trait BothDebug {
11
    fn __dispatch_ensure(self, msg: &'static str) -> Error;
12
}
13
14
impl<A, B> BothDebug for (A, B)
15
where
16
    A: Debug,
17
    B: Debug,
18
{
19
0
    fn __dispatch_ensure(self, msg: &'static str) -> Error {
20
0
        render(msg, &self.0, &self.1)
21
0
    }
22
}
23
24
#[doc(hidden)]
25
pub trait NotBothDebug {
26
    fn __dispatch_ensure(self, msg: &'static str) -> Error;
27
}
28
29
impl<A, B> NotBothDebug for &(A, B) {
30
0
    fn __dispatch_ensure(self, msg: &'static str) -> Error {
31
0
        Error::msg(msg)
32
0
    }
33
}
34
35
struct Buf {
36
    bytes: [MaybeUninit<u8>; 40],
37
    written: usize,
38
}
39
40
impl Buf {
41
0
    fn new() -> Self {
42
0
        Buf {
43
0
            bytes: [MaybeUninit::uninit(); 40],
44
0
            written: 0,
45
0
        }
46
0
    }
47
48
0
    fn as_str(&self) -> &str {
49
0
        unsafe {
50
0
            str::from_utf8_unchecked(slice::from_raw_parts(
51
0
                self.bytes.as_ptr().cast::<u8>(),
52
0
                self.written,
53
0
            ))
54
0
        }
55
0
    }
56
}
57
58
impl Write for Buf {
59
0
    fn write_str(&mut self, s: &str) -> fmt::Result {
60
0
        if s.bytes().any(|b| b == b' ' || b == b'\n') {
61
0
            return Err(fmt::Error);
62
0
        }
63
0
64
0
        let remaining = self.bytes.len() - self.written;
65
0
        if s.len() > remaining {
66
0
            return Err(fmt::Error);
67
0
        }
68
0
69
0
        unsafe {
70
0
            ptr::copy_nonoverlapping(
71
0
                s.as_ptr(),
72
0
                self.bytes.as_mut_ptr().add(self.written).cast::<u8>(),
73
0
                s.len(),
74
0
            );
75
0
        }
76
0
        self.written += s.len();
77
0
        Ok(())
78
0
    }
79
}
80
81
0
fn render(msg: &'static str, lhs: &dyn Debug, rhs: &dyn Debug) -> Error {
82
0
    let mut lhs_buf = Buf::new();
83
0
    if fmt::write(&mut lhs_buf, format_args!("{:?}", lhs)).is_ok() {
84
0
        let mut rhs_buf = Buf::new();
85
0
        if fmt::write(&mut rhs_buf, format_args!("{:?}", rhs)).is_ok() {
86
0
            let lhs_str = lhs_buf.as_str();
87
0
            let rhs_str = rhs_buf.as_str();
88
0
            // "{msg} ({lhs} vs {rhs})"
89
0
            let len = msg.len() + 2 + lhs_str.len() + 4 + rhs_str.len() + 1;
90
0
            let mut string = String::with_capacity(len);
91
0
            string.push_str(msg);
92
0
            string.push_str(" (");
93
0
            string.push_str(lhs_str);
94
0
            string.push_str(" vs ");
95
0
            string.push_str(rhs_str);
96
0
            string.push(')');
97
0
            return Error::msg(string);
98
0
        }
99
0
    }
100
0
    Error::msg(msg)
101
0
}
102
103
#[doc(hidden)]
104
#[macro_export]
105
macro_rules! __parse_ensure {
106
    (atom () $bail:tt $fuel:tt {($($rhs:tt)+) ($($lhs:tt)+) $op:tt} $dup:tt $(,)?) => {
107
        $crate::__fancy_ensure!($($lhs)+, $op, $($rhs)+)
108
    };
109
110
    // low precedence control flow constructs
111
112
    (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt return $($rest:tt)*) => {
113
        $crate::__fallback_ensure!($($bail)*)
114
    };
115
116
    (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt break $($rest:tt)*) => {
117
        $crate::__fallback_ensure!($($bail)*)
118
    };
119
120
    (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt continue $($rest:tt)*) => {
121
        $crate::__fallback_ensure!($($bail)*)
122
    };
123
124
    (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt yield $($rest:tt)*) => {
125
        $crate::__fallback_ensure!($($bail)*)
126
    };
127
128
    (0 $stack:tt ($($bail:tt)*) $fuel:tt $parse:tt $dup:tt move $($rest:tt)*) => {
129
        $crate::__fallback_ensure!($($bail)*)
130
    };
131
132
    // unary operators
133
134
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($deref:tt $($dup:tt)*) * $($rest:tt)*) => {
135
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $deref) $($parse)*} ($($rest)*) $($rest)*)
136
    };
137
138
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($not:tt $($dup:tt)*) ! $($rest:tt)*) => {
139
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $not) $($parse)*} ($($rest)*) $($rest)*)
140
    };
141
142
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($neg:tt $($dup:tt)*) - $($rest:tt)*) => {
143
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $neg) $($parse)*} ($($rest)*) $($rest)*)
144
    };
145
146
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($let:tt $($dup:tt)*) let $($rest:tt)*) => {
147
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $let) $($parse)*} ($($rest)*) $($rest)*)
148
    };
149
150
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($lifetime:tt $colon:tt $($dup:tt)*) $label:lifetime : $($rest:tt)*) => {
151
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $lifetime $colon) $($parse)*} ($($rest)*) $($rest)*)
152
    };
153
154
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) &mut $($rest:tt)*) => {
155
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
156
    };
157
158
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
159
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
160
    };
161
162
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $mut:tt $($dup:tt)*) &&mut $($rest:tt)*) => {
163
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $andand $mut) $($parse)*} ($($rest)*) $($rest)*)
164
    };
165
166
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $($dup:tt)*) && $($rest:tt)*) => {
167
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $andand) $($parse)*} ($($rest)*) $($rest)*)
168
    };
169
170
    // control flow constructs
171
172
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($if:tt $($dup:tt)*) if $($rest:tt)*) => {
173
        $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $if) $($parse)*} ($($rest)*) $($rest)*)
174
    };
175
176
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($match:tt $($dup:tt)*) match $($rest:tt)*) => {
177
        $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $match) $($parse)*} ($($rest)*) $($rest)*)
178
    };
179
180
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($while:tt $($dup:tt)*) while $($rest:tt)*) => {
181
        $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $while) $($parse)*} ($($rest)*) $($rest)*)
182
    };
183
184
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($for:tt $($dup:tt)*) for $($rest:tt)*) => {
185
        $crate::__parse_ensure!(pat (cond $stack) $bail ($($fuel)*) {($($buf)* $for) $($parse)*} ($($rest)*) $($rest)*)
186
    };
187
188
    (atom (cond $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
189
        $crate::__parse_ensure!(cond $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
190
    };
191
192
    (cond $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($else:tt $if:tt $($dup:tt)*) else if $($rest:tt)*) => {
193
        $crate::__parse_ensure!(0 (cond $stack) $bail ($($fuel)*) {($($buf)* $else $if) $($parse)*} ($($rest)*) $($rest)*)
194
    };
195
196
    (cond $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($else:tt $brace:tt $($dup:tt)*) else {$($block:tt)*} $($rest:tt)*) => {
197
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $else $brace) $($parse)*} ($($rest)*) $($rest)*)
198
    };
199
200
    (cond $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
201
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) $parse $dup $($rest)*)
202
    };
203
204
    // atomic expressions
205
206
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
207
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
208
    };
209
210
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($array:tt)*] $($rest:tt)*) => {
211
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
212
    };
213
214
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
215
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
216
    };
217
218
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($loop:tt $block:tt $($dup:tt)*) loop {$($body:tt)*} $($rest:tt)*) => {
219
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $loop $block) $($parse)*} ($($rest)*) $($rest)*)
220
    };
221
222
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($async:tt $block:tt $($dup:tt)*) async {$($body:tt)*} $($rest:tt)*) => {
223
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $async $block) $($parse)*} ($($rest)*) $($rest)*)
224
    };
225
226
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($async:tt $move:tt $block:tt $($dup:tt)*) async move {$($body:tt)*} $($rest:tt)*) => {
227
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $async $move $block) $($parse)*} ($($rest)*) $($rest)*)
228
    };
229
230
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $block:tt $($dup:tt)*) unsafe {$($body:tt)*} $($rest:tt)*) => {
231
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $unsafe $block) $($parse)*} ($($rest)*) $($rest)*)
232
    };
233
234
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($const:tt $block:tt $($dup:tt)*) const {$($body:tt)*} $($rest:tt)*) => {
235
        // TODO: this is mostly useless due to https://github.com/rust-lang/rust/issues/86730
236
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $const $block) $($parse)*} ($($rest)*) $($rest)*)
237
    };
238
239
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($literal:tt $($dup:tt)*) $lit:literal $($rest:tt)*) => {
240
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $literal) $($parse)*} ($($rest)*) $($rest)*)
241
    };
242
243
    // path expressions
244
245
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => {
246
        $crate::__parse_ensure!(epath (atom $stack) $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
247
    };
248
249
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ident:tt $($dup:tt)*) $i:ident $($rest:tt)*) => {
250
        $crate::__parse_ensure!(epath (atom $stack) $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
251
    };
252
253
    (0 $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
254
        $crate::__parse_ensure!(type (qpath (epath (atom $stack))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
255
    };
256
257
    (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: < $($rest:tt)*) => {
258
        $crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
259
    };
260
261
    (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: << $($rest:tt)*) => {
262
        $crate::__parse_ensure!(type (qpath (tpath (arglist (epath $stack)))) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
263
    };
264
265
    (epath $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt :: <- - $($rest:tt)*) => {
266
        $crate::__fallback_ensure!($($bail)*)
267
    };
268
269
    (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $larrow:tt $($dup:tt)*) :: <- $lit:literal $($rest:tt)*) => {
270
        $crate::__parse_ensure!(generic (epath $stack) $bail ($($fuel)*) {($($buf)* $colons $larrow) $($parse)*} ($($dup)*) $($dup)*)
271
    };
272
273
    (epath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => {
274
        $crate::__parse_ensure!(epath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
275
    };
276
277
    (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => {
278
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
279
    };
280
281
    (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! [$($mac:tt)*] $($rest:tt)*) => {
282
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
283
    };
284
285
    (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! {$($mac:tt)*} $($rest:tt)*) => {
286
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
287
    };
288
289
    (epath (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
290
        $crate::__parse_ensure!($pop (split $stack) $bail ($($fuel)*) $parse $dup $($rest)*)
291
    };
292
293
    (epath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
294
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*)
295
    };
296
297
    // trailer expressions
298
299
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($call:tt)*) $($rest:tt)*) => {
300
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
301
    };
302
303
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($index:tt)*] $($rest:tt)*) => {
304
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
305
    };
306
307
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($init:tt)*} $($rest:tt)*) => {
308
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
309
    };
310
311
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($question:tt $($dup:tt)*) ? $($rest:tt)*) => {
312
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $question) $($parse)*} ($($rest)*) $($rest)*)
313
    };
314
315
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $langle:tt $($dup:tt)*) . $i:ident :: < $($rest:tt)*) => {
316
        $crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
317
    };
318
319
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $langle:tt $($dup:tt)*) . $i:ident :: << $($rest:tt)*) => {
320
        $crate::__parse_ensure!(type (qpath (tpath (arglist (atom $stack)))) $bail ($($fuel)*) {($($buf)* $dot $ident $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
321
    };
322
323
    (atom $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt . $i:ident :: <- - $($rest:tt)*) => {
324
        $crate::__fallback_ensure!($($bail)*)
325
    };
326
327
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $ident:tt $colons:tt $larrow:tt $($dup:tt)*) . $i:ident :: <- $lit:literal $($rest:tt)*) => {
328
        $crate::__parse_ensure!(generic (atom $stack) $bail ($($fuel)*) {($($buf)* $dot $ident $colons $larrow) $($parse)*} ($($dup)*) $($dup)*)
329
    };
330
331
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $field:tt $($dup:tt)*) . $i:ident $($rest:tt)*) => {
332
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $dot $field) $($parse)*} ($($rest)*) $($rest)*)
333
    };
334
335
    (atom $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt . - $($rest:tt)*) => {
336
        $crate::__fallback_ensure!($($bail)*)
337
    };
338
339
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dot:tt $index:tt $($dup:tt)*) . $lit:literal $($rest:tt)*) => {
340
        $crate::__parse_ensure!(atom $stack $bail ($($fuel)*) {($($buf)* $dot $index) $($parse)*} ($($rest)*) $($rest)*)
341
    };
342
343
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($as:tt $($dup:tt)*) as $($rest:tt)*) => {
344
        $crate::__parse_ensure!(type (atom $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*)
345
    };
346
347
    // types
348
349
    (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($content:tt)*] $($rest:tt)*) => {
350
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
351
    };
352
353
    (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
354
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
355
    };
356
357
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($star:tt $const:tt $($dup:tt)*) *const $($rest:tt)*) => {
358
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $star $const) $($parse)*} ($($rest)*) $($rest)*)
359
    };
360
361
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($star:tt $mut:tt $($dup:tt)*) *mut $($rest:tt)*) => {
362
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $star $mut) $($parse)*} ($($rest)*) $($rest)*)
363
    };
364
365
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $lifetime:tt $mut:tt $($dup:tt)*) & $l:lifetime mut $($rest:tt)*) => {
366
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $lifetime $mut) $($parse)*} ($($rest)*) $($rest)*)
367
    };
368
369
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) & mut $($rest:tt)*) => {
370
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
371
    };
372
373
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $lifetime:tt $($dup:tt)*) & $l:lifetime $($rest:tt)*) => {
374
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $lifetime) $($parse)*} ($($rest)*) $($rest)*)
375
    };
376
377
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
378
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
379
    };
380
381
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $lifetime:tt $mut:tt $($dup:tt)*) && $l:lifetime mut $($rest:tt)*) => {
382
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $lifetime $mut) $($parse)*} ($($rest)*) $($rest)*)
383
    };
384
385
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $mut:tt $($dup:tt)*) && mut $($rest:tt)*) => {
386
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $mut) $($parse)*} ($($rest)*) $($rest)*)
387
    };
388
389
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $lifetime:tt $($dup:tt)*) && $l:lifetime $($rest:tt)*) => {
390
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and $lifetime) $($parse)*} ($($rest)*) $($rest)*)
391
    };
392
393
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) && $($rest:tt)*) => {
394
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
395
    };
396
397
    (type $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt unsafe extern - $($rest:tt)*) => {
398
        $crate::__fallback_ensure!($($bail)*)
399
    };
400
401
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($unsafe:tt $(extern $($abi:literal)?)? fn $($dup:tt)*) unsafe $($rest:tt)*) => {
402
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $unsafe) $($parse)*} ($($rest)*) $($rest)*)
403
    };
404
405
    (type $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt extern - $($rest:tt)*) => {
406
        $crate::__fallback_ensure!($($bail)*)
407
    };
408
409
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt $abi:tt fn $($dup:tt)*) extern $lit:literal $($rest:tt)*) => {
410
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern $abi) $($parse)*} ($($rest)*) $($rest)*)
411
    };
412
413
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($extern:tt fn $($dup:tt)*) extern $($rest:tt)*) => {
414
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $extern) $($parse)*} ($($rest)*) $($rest)*)
415
    };
416
417
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $arrow:tt $($dup:tt)*) fn ($($args:tt)*) -> $($rest:tt)*) => {
418
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $fn $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
419
    };
420
421
    (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($fn:tt $paren:tt $($dup:tt)*) fn ($($args:tt)*) $($rest:tt)*) => {
422
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $fn $paren) $($parse)*} ($($rest)*) $($rest)*)
423
    };
424
425
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($impl:tt $($dup:tt)*) impl $($rest:tt)*) => {
426
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $impl) $($parse)*} ($($rest)*) $($rest)*)
427
    };
428
429
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($dyn:tt $($dup:tt)*) dyn $($rest:tt)*) => {
430
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $dyn) $($parse)*} ($($rest)*) $($rest)*)
431
    };
432
433
    (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($wild:tt $($dup:tt)*) _ $($rest:tt)*) => {
434
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $wild) $($parse)*} ($($rest)*) $($rest)*)
435
    };
436
437
    (type ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($never:tt $($dup:tt)*) ! $($rest:tt)*) => {
438
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $never) $($parse)*} ($($rest)*) $($rest)*)
439
    };
440
441
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($for:tt $langle:tt $($dup:tt)*) for < $($rest:tt)*) => {
442
        $crate::__parse_ensure!(generic (type $stack) $bail ($($fuel)*) {($($buf)* $for $langle) $($parse)*} ($($rest)*) $($rest)*)
443
    };
444
445
    // path types
446
447
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => {
448
        $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
449
    };
450
451
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ident:tt $($dup:tt)*) $i:ident $($rest:tt)*) => {
452
        $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
453
    };
454
455
    (type $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
456
        $crate::__parse_ensure!(type (qpath (tpath $stack)) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
457
    };
458
459
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
460
        $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
461
    };
462
463
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) << $($rest:tt)*) => {
464
        $crate::__parse_ensure!(type (qpath (tpath (arglist (tpath $stack)))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
465
    };
466
467
    (tpath $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt <- - $($rest:tt)*) => {
468
        $crate::__fallback_ensure!($($bail)*)
469
    };
470
471
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($larrow:tt $($dup:tt)*) <- $lit:literal $($rest:tt)*) => {
472
        $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $larrow) $($parse)*} ($($dup)*) $($dup)*)
473
    };
474
475
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: < $($rest:tt)*) => {
476
        $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
477
    };
478
479
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $langle:tt $($dup:tt)*) :: << $($rest:tt)*) => {
480
        $crate::__parse_ensure!(type (qpath (tpath (arglist (tpath $stack)))) $bail ($($fuel)*) {($($buf)* $colons $langle) $($parse)*} ($($rest)*) $($rest)*)
481
    };
482
483
    (tpath $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt :: <- - $($rest:tt)*) => {
484
        $crate::__fallback_ensure!($($bail)*)
485
    };
486
487
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $larrow:tt $($dup:tt)*) :: <- $lit:literal $($rest:tt)*) => {
488
        $crate::__parse_ensure!(generic (tpath $stack) $bail ($($fuel)*) {($($buf)* $colons $larrow) $($parse)*} ($($dup)*) $($dup)*)
489
    };
490
491
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => {
492
        $crate::__parse_ensure!(tpath $stack $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
493
    };
494
495
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $arrow:tt $($dup:tt)*) ($($args:tt)*) -> $($rest:tt)*) => {
496
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
497
    };
498
499
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($args:tt)*) $($rest:tt)*) => {
500
        $crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
501
    };
502
503
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $arrow:tt $($dup:tt)*) :: ($($args:tt)*) -> $($rest:tt)*) => {
504
        $crate::__parse_ensure!(type $stack $bail ($($fuel)*) {($($buf)* $colons $paren $arrow) $($parse)*} ($($rest)*) $($rest)*)
505
    };
506
507
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $paren:tt $($dup:tt)*) :: ($($args:tt)*) $($rest:tt)*) => {
508
        $crate::__parse_ensure!(object $stack $bail ($($fuel)*) {($($buf)* $colons $paren) $($parse)*} ($($rest)*) $($rest)*)
509
    };
510
511
    (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! ($($mac:tt)*) $($rest:tt)*) => {
512
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
513
    };
514
515
    (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! [$($mac:tt)*] $($rest:tt)*) => {
516
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
517
    };
518
519
    (tpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bang:tt $args:tt $($dup:tt)*) ! {$($mac:tt)*} $($rest:tt)*) => {
520
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $bang $args) $($parse)*} ($($rest)*) $($rest)*)
521
    };
522
523
    (tpath $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
524
        $crate::__parse_ensure!(object $stack $bail ($($fuel)*) $parse $dup $($rest)*)
525
    };
526
527
    // qualified paths
528
529
    (qpath (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $colons:tt $ident:tt $($dup:tt)*) >> :: $i:ident $($rest:tt)*) => {
530
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
531
    };
532
533
    (qpath ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $colons:tt $ident:tt $($dup:tt)*) > :: $i:ident $($rest:tt)*) => {
534
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
535
    };
536
537
    (qpath $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($as:tt $($dup:tt)*) as $($rest:tt)*) => {
538
        $crate::__parse_ensure!(type (qpath $stack) $bail ($($fuel)*) {($($buf)* $as) $($parse)*} ($($rest)*) $($rest)*)
539
    };
540
541
    // trait objects
542
543
    (object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $colons:tt $ident:tt $($dup:tt)*) + :: $i:ident $($rest:tt)*) => {
544
        $crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
545
    };
546
547
    (object (arglist $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($plus:tt $ident:tt $($dup:tt)*) + $i:ident $($rest:tt)*) => {
548
        $crate::__parse_ensure!(tpath (arglist $stack) $bail ($($fuel)*) {($($buf)* $plus $ident) $($parse)*} ($($rest)*) $($rest)*)
549
    };
550
551
    (object (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
552
        $crate::__parse_ensure!($pop (split $stack) $bail ($($fuel)*) $parse $dup $($rest)*)
553
    };
554
555
    (object ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
556
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) $parse $dup $($rest)*)
557
    };
558
559
    // angle bracketed generic arguments
560
561
    (generic (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => {
562
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*)
563
    };
564
565
    (generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => {
566
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*)
567
    };
568
569
    (generic ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => {
570
        $crate::__parse_ensure!($pop (split $stack) $bail ($($fuel)*) {($($buf)*) $($parse)*} ($rangle $($rest)*) $rangle $($rest)*)
571
    };
572
573
    (generic $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt - - $($rest:tt)*) => {
574
        $crate::__fallback_ensure!($($bail)*)
575
    };
576
577
    (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($neg:tt $($dup:tt)*) - $lit:literal $($rest:tt)*) => {
578
        $crate::__parse_ensure!(generic $stack $bail ($($fuel)*) {($($buf)* $neg) $($parse)*} ($($dup)*) $($dup)*)
579
    };
580
581
    (generic $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt - $($rest:tt)*) => {
582
        $crate::__fallback_ensure!($($bail)*)
583
    };
584
585
    (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($literal:tt $($dup:tt)*) $lit:literal $($rest:tt)*) => {
586
        $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $literal) $($parse)*} ($($rest)*) $($rest)*)
587
    };
588
589
    (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($block:tt)*} $($rest:tt)*) => {
590
        $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
591
    };
592
593
    (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($lifetime:tt $($dup:tt)*) $l:lifetime $($rest:tt)*) => {
594
        $crate::__parse_ensure!(arglist $stack $bail ($($fuel)*) {($($buf)* $lifetime) $($parse)*} ($($rest)*) $($rest)*)
595
    };
596
597
    (generic $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($assoc:tt $eq:tt $($dup:tt)*) $ident:ident = $($rest:tt)*) => {
598
        $crate::__parse_ensure!(type (arglist $stack) $bail ($($fuel)*) {($($buf)* $assoc $eq) $($parse)*} ($($rest)*) $($rest)*)
599
    };
600
601
    (generic $stack:tt $bail:tt (~$($fuel:tt)*) $parse:tt $dup:tt $($rest:tt)*) => {
602
        $crate::__parse_ensure!(type (arglist $stack) $bail ($($fuel)*) $parse $dup $($rest)*)
603
    };
604
605
    (arglist $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($comma:tt $($dup:tt)*) , $($rest:tt)*) => {
606
        $crate::__parse_ensure!(generic $stack $bail ($($fuel)*) {($($buf)* $comma) $($parse)*} ($($rest)*) $($rest)*)
607
    };
608
609
    (arglist (split ($pop:ident $stack:tt)) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => {
610
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)*) $rangle $($parse)*} ($($rest)*) $($rest)*)
611
    };
612
613
    (arglist ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) > $($rest:tt)*) => {
614
        $crate::__parse_ensure!($pop $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*)
615
    };
616
617
    (arglist ($pop:ident $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => {
618
        $crate::__parse_ensure!($pop (split $stack) $bail ($($fuel)*) {($($buf)*) $($parse)*} ($rangle $($rest)*) $rangle $($rest)*)
619
    };
620
621
    // patterns
622
623
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($pipe:tt $($dup:tt)*) | $($rest:tt)*) => {
624
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $pipe) $($parse)*} ($($rest)*) $($rest)*)
625
    };
626
627
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($eq:tt $($dup:tt)*) = $($rest:tt)*) => {
628
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $eq) $($parse)*} ($($rest)*) $($rest)*)
629
    };
630
631
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($in:tt $($dup:tt)*) in $($rest:tt)*) => {
632
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $in) $($parse)*} ($($rest)*) $($rest)*)
633
    };
634
635
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ref:tt $($dup:tt)*) ref $($rest:tt)*) => {
636
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $ref) $($parse)*} ($($rest)*) $($rest)*)
637
    };
638
639
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($mut:tt $($dup:tt)*) mut $($rest:tt)*) => {
640
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $mut) $($parse)*} ($($rest)*) $($rest)*)
641
    };
642
643
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($at:tt $($dup:tt)*) @ $($rest:tt)*) => {
644
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $at) $($parse)*} ($($rest)*) $($rest)*)
645
    };
646
647
    (pat $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt - - $($rest:tt)*) => {
648
        $crate::__fallback_ensure!($($bail)*)
649
    };
650
651
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($neg:tt $($dup:tt)*) - $lit:literal $($rest:tt)*) => {
652
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $neg) $($parse)*} ($($dup)*) $($dup)*)
653
    };
654
655
    (pat $stack:tt ($($bail:tt)*) (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt - $($rest:tt)*) => {
656
        $crate::__fallback_ensure!($($bail)*)
657
    };
658
659
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($literal:tt $($dup:tt)*) $lit:literal $($rest:tt)*) => {
660
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $literal) $($parse)*} ($($rest)*) $($rest)*)
661
    };
662
663
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($range:tt $($dup:tt)*) .. $($rest:tt)*) => {
664
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $range) $($parse)*} ($($rest)*) $($rest)*)
665
    };
666
667
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($range:tt $($dup:tt)*) ..= $($rest:tt)*) => {
668
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $range) $($parse)*} ($($rest)*) $($rest)*)
669
    };
670
671
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) & $($rest:tt)*) => {
672
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
673
    };
674
675
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($andand:tt $($dup:tt)*) && $($rest:tt)*) => {
676
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $andand) $($parse)*} ($($rest)*) $($rest)*)
677
    };
678
679
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($paren:tt $($dup:tt)*) ($($content:tt)*) $($rest:tt)*) => {
680
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $paren) $($parse)*} ($($rest)*) $($rest)*)
681
    };
682
683
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bracket:tt $($dup:tt)*) [$($content:tt)*] $($rest:tt)*) => {
684
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $bracket) $($parse)*} ($($rest)*) $($rest)*)
685
    };
686
687
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($brace:tt $($dup:tt)*) {$($content:tt)*} $($rest:tt)*) => {
688
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $brace) $($parse)*} ($($rest)*) $($rest)*)
689
    };
690
691
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($wild:tt $($dup:tt)*) _ $($rest:tt)*) => {
692
        $crate::__parse_ensure!(pat $stack $bail ($($fuel)*) {($($buf)* $wild) $($parse)*} ($($rest)*) $($rest)*)
693
    };
694
695
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($colons:tt $ident:tt $($dup:tt)*) :: $i:ident $($rest:tt)*) => {
696
        $crate::__parse_ensure!(epath (pat $stack) $bail ($($fuel)*) {($($buf)* $colons $ident) $($parse)*} ($($rest)*) $($rest)*)
697
    };
698
699
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ident:tt $($dup:tt)*) $i:ident $($rest:tt)*) => {
700
        $crate::__parse_ensure!(epath (pat $stack) $bail ($($fuel)*) {($($buf)* $ident) $($parse)*} ($($rest)*) $($rest)*)
701
    };
702
703
    (pat $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($langle:tt $($dup:tt)*) < $($rest:tt)*) => {
704
        $crate::__parse_ensure!(type (qpath (epath (pat $stack))) $bail ($($fuel)*) {($($buf)* $langle) $($parse)*} ($($rest)*) $($rest)*)
705
    };
706
707
    // comparison binary operators
708
709
    (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($eq:tt $($dup:tt)*) == $($rest:tt)*) => {
710
        $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $eq} ($($rest)*) $($rest)*)
711
    };
712
713
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($eq:tt $($dup:tt)*) == $($rest:tt)*) => {
714
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $eq) $($parse)*} ($($rest)*) $($rest)*)
715
    };
716
717
    (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($le:tt $($dup:tt)*) <= $($rest:tt)*) => {
718
        $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $le} ($($rest)*) $($rest)*)
719
    };
720
721
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($le:tt $($dup:tt)*) <= $($rest:tt)*) => {
722
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $le) $($parse)*} ($($rest)*) $($rest)*)
723
    };
724
725
    (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($lt:tt $($dup:tt)*) < $($rest:tt)*) => {
726
        $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $lt} ($($rest)*) $($rest)*)
727
    };
728
729
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($lt:tt $($dup:tt)*) < $($rest:tt)*) => {
730
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $lt) $($parse)*} ($($rest)*) $($rest)*)
731
    };
732
733
    (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ne:tt $($dup:tt)*) != $($rest:tt)*) => {
734
        $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $ne} ($($rest)*) $($rest)*)
735
    };
736
737
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($ne:tt $($dup:tt)*) != $($rest:tt)*) => {
738
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $ne) $($parse)*} ($($rest)*) $($rest)*)
739
    };
740
741
    (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($ge:tt $($dup:tt)*) >= $($rest:tt)*) => {
742
        $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $ge} ($($rest)*) $($rest)*)
743
    };
744
745
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($ge:tt $($dup:tt)*) >= $($rest:tt)*) => {
746
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $ge) $($parse)*} ($($rest)*) $($rest)*)
747
    };
748
749
    (atom (split ()) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} $dup:tt >> $($rest:tt)*) => {
750
        $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)* > ) > } ($($rest)*) $($rest)*)
751
    };
752
753
    (atom () $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($gt:tt $($dup:tt)*) > $($rest:tt)*) => {
754
        $crate::__parse_ensure!(0 () $bail ($($fuel)*) {() $($parse)* ($($buf)*) $gt} ($($rest)*) $($rest)*)
755
    };
756
757
    (atom (split $stack:tt) $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($rangle:tt $($dup:tt)*) >> $($rest:tt)*) => {
758
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $rangle) $($parse)*} ($($rest)*) $($rest)*)
759
    };
760
761
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)+) $($parse:tt)*} ($gt:tt $($dup:tt)*) > $($rest:tt)*) => {
762
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $gt) $($parse)*} ($($rest)*) $($rest)*)
763
    };
764
765
    // high precedence binary operators
766
767
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($add:tt $($dup:tt)*) + $($rest:tt)*) => {
768
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $add) $($parse)*} ($($rest)*) $($rest)*)
769
    };
770
771
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($sub:tt $($dup:tt)*) - $($rest:tt)*) => {
772
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $sub) $($parse)*} ($($rest)*) $($rest)*)
773
    };
774
775
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($mul:tt $($dup:tt)*) * $($rest:tt)*) => {
776
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $mul) $($parse)*} ($($rest)*) $($rest)*)
777
    };
778
779
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($div:tt $($dup:tt)*) / $($rest:tt)*) => {
780
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $div) $($parse)*} ($($rest)*) $($rest)*)
781
    };
782
783
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($rem:tt $($dup:tt)*) % $($rest:tt)*) => {
784
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $rem) $($parse)*} ($($rest)*) $($rest)*)
785
    };
786
787
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitxor:tt $($dup:tt)*) ^ $($rest:tt)*) => {
788
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitxor) $($parse)*} ($($rest)*) $($rest)*)
789
    };
790
791
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitand:tt $($dup:tt)*) & $($rest:tt)*) => {
792
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitand) $($parse)*} ($($rest)*) $($rest)*)
793
    };
794
795
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitor:tt $($dup:tt)*) | $($rest:tt)*) => {
796
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $bitor) $($parse)*} ($($rest)*) $($rest)*)
797
    };
798
799
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shl:tt $($dup:tt)*) << $($rest:tt)*) => {
800
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $shl) $($parse)*} ($($rest)*) $($rest)*)
801
    };
802
803
    (atom $stack:tt $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shr:tt $($dup:tt)*) >> $($rest:tt)*) => {
804
        $crate::__parse_ensure!(0 $stack $bail ($($fuel)*) {($($buf)* $shr) $($parse)*} ($($rest)*) $($rest)*)
805
    };
806
807
    // low precedence binary operators
808
809
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($and:tt $($dup:tt)*) && $($rest:tt)*) => {
810
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $and) $($parse)*} ($($rest)*) $($rest)*)
811
    };
812
813
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($or:tt $($dup:tt)*) || $($rest:tt)*) => {
814
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $or) $($parse)*} ($($rest)*) $($rest)*)
815
    };
816
817
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($assign:tt $($dup:tt)*) = $($rest:tt)*) => {
818
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $assign) $($parse)*} ($($rest)*) $($rest)*)
819
    };
820
821
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($addeq:tt $($dup:tt)*) += $($rest:tt)*) => {
822
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $addeq) $($parse)*} ($($rest)*) $($rest)*)
823
    };
824
825
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($subeq:tt $($dup:tt)*) -= $($rest:tt)*) => {
826
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $subeq) $($parse)*} ($($rest)*) $($rest)*)
827
    };
828
829
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($muleq:tt $($dup:tt)*) *= $($rest:tt)*) => {
830
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $muleq) $($parse)*} ($($rest)*) $($rest)*)
831
    };
832
833
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($diveq:tt $($dup:tt)*) /= $($rest:tt)*) => {
834
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $diveq) $($parse)*} ($($rest)*) $($rest)*)
835
    };
836
837
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($remeq:tt $($dup:tt)*) %= $($rest:tt)*) => {
838
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $remeq) $($parse)*} ($($rest)*) $($rest)*)
839
    };
840
841
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitxoreq:tt $($dup:tt)*) ^= $($rest:tt)*) => {
842
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitxoreq) $($parse)*} ($($rest)*) $($rest)*)
843
    };
844
845
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitandeq:tt $($dup:tt)*) &= $($rest:tt)*) => {
846
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitandeq) $($parse)*} ($($rest)*) $($rest)*)
847
    };
848
849
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($bitoreq:tt $($dup:tt)*) |= $($rest:tt)*) => {
850
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $bitoreq) $($parse)*} ($($rest)*) $($rest)*)
851
    };
852
853
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shleq:tt $($dup:tt)*) <<= $($rest:tt)*) => {
854
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $shleq) $($parse)*} ($($rest)*) $($rest)*)
855
    };
856
857
    (atom ($($stack:tt)+) $bail:tt (~$($fuel:tt)*) {($($buf:tt)*) $($parse:tt)*} ($shreq:tt $($dup:tt)*) >>= $($rest:tt)*) => {
858
        $crate::__parse_ensure!(0 ($($stack)*) $bail ($($fuel)*) {($($buf)* $shreq) $($parse)*} ($($rest)*) $($rest)*)
859
    };
860
861
    // unrecognized expression
862
863
    ($state:tt $stack:tt ($($bail:tt)*) $($rest:tt)*) => {
864
        $crate::__fallback_ensure!($($bail)*)
865
    };
866
}
867
868
#[doc(hidden)]
869
#[macro_export]
870
macro_rules! __fancy_ensure {
871
    ($lhs:expr, $op:tt, $rhs:expr) => {
872
        match (&$lhs, &$rhs) {
873
            (lhs, rhs) => {
874
                if !(lhs $op rhs) {
875
                    #[allow(unused_imports)]
876
                    use $crate::__private::{BothDebug, NotBothDebug};
877
                    return Err((lhs, rhs).__dispatch_ensure(
878
                        $crate::__private::concat!(
879
                            "Condition failed: `",
880
                            $crate::__private::stringify!($lhs),
881
                            " ",
882
                            $crate::__private::stringify!($op),
883
                            " ",
884
                            $crate::__private::stringify!($rhs),
885
                            "`",
886
                        ),
887
                    ));
888
                }
889
            }
890
        }
891
    };
892
}
893
894
#[doc(hidden)]
895
#[macro_export]
896
macro_rules! __fallback_ensure {
897
    ($cond:expr $(,)?) => {
898
        if $crate::__private::not($cond) {
899
            return $crate::__private::Err($crate::Error::msg(
900
                $crate::__private::concat!("Condition failed: `", $crate::__private::stringify!($cond), "`")
901
            ));
902
        }
903
    };
904
    ($cond:expr, $msg:literal $(,)?) => {
905
        if $crate::__private::not($cond) {
906
            return $crate::__private::Err($crate::__anyhow!($msg));
907
        }
908
    };
909
    ($cond:expr, $err:expr $(,)?) => {
910
        if $crate::__private::not($cond) {
911
            return $crate::__private::Err($crate::__anyhow!($err));
912
        }
913
    };
914
    ($cond:expr, $fmt:expr, $($arg:tt)*) => {
915
        if $crate::__private::not($cond) {
916
            return $crate::__private::Err($crate::__anyhow!($fmt, $($arg)*));
917
        }
918
    };
919
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/error.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::backtrace::Backtrace;
2
use crate::chain::Chain;
3
#[cfg(any(feature = "std", anyhow_no_ptr_addr_of))]
4
use crate::ptr::Mut;
5
use crate::ptr::{Own, Ref};
6
use crate::{Error, StdError};
7
use alloc::boxed::Box;
8
use core::any::TypeId;
9
use core::fmt::{self, Debug, Display};
10
use core::mem::ManuallyDrop;
11
#[cfg(not(anyhow_no_ptr_addr_of))]
12
use core::ptr;
13
use core::ptr::NonNull;
14
#[cfg(error_generic_member_access)]
15
use std::error::{self, Request};
16
17
#[cfg(feature = "std")]
18
use core::ops::{Deref, DerefMut};
19
20
impl Error {
21
    /// Create a new error object from any error type.
22
    ///
23
    /// The error type must be threadsafe and `'static`, so that the `Error`
24
    /// will be as well.
25
    ///
26
    /// If the error type does not provide a backtrace, a backtrace will be
27
    /// created here to ensure that a backtrace exists.
28
    #[cfg(feature = "std")]
29
    #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
30
    #[cold]
31
    #[must_use]
32
0
    pub fn new<E>(error: E) -> Self
33
0
    where
34
0
        E: StdError + Send + Sync + 'static,
35
0
    {
36
0
        let backtrace = backtrace_if_absent!(&error);
37
0
        Error::from_std(error, backtrace)
38
0
    }
39
40
    /// Create a new error object from a printable error message.
41
    ///
42
    /// If the argument implements std::error::Error, prefer `Error::new`
43
    /// instead which preserves the underlying error's cause chain and
44
    /// backtrace. If the argument may or may not implement std::error::Error
45
    /// now or in the future, use `anyhow!(err)` which handles either way
46
    /// correctly.
47
    ///
48
    /// `Error::msg("...")` is equivalent to `anyhow!("...")` but occasionally
49
    /// convenient in places where a function is preferable over a macro, such
50
    /// as iterator or stream combinators:
51
    ///
52
    /// ```
53
    /// # mod ffi {
54
    /// #     pub struct Input;
55
    /// #     pub struct Output;
56
    /// #     pub async fn do_some_work(_: Input) -> Result<Output, &'static str> {
57
    /// #         unimplemented!()
58
    /// #     }
59
    /// # }
60
    /// #
61
    /// # use ffi::{Input, Output};
62
    /// #
63
    /// use anyhow::{Error, Result};
64
    /// use futures::stream::{Stream, StreamExt, TryStreamExt};
65
    ///
66
    /// async fn demo<S>(stream: S) -> Result<Vec<Output>>
67
    /// where
68
    ///     S: Stream<Item = Input>,
69
    /// {
70
    ///     stream
71
    ///         .then(ffi::do_some_work) // returns Result<Output, &str>
72
    ///         .map_err(Error::msg)
73
    ///         .try_collect()
74
    ///         .await
75
    /// }
76
    /// ```
77
    #[cold]
78
    #[must_use]
79
0
    pub fn msg<M>(message: M) -> Self
80
0
    where
81
0
        M: Display + Debug + Send + Sync + 'static,
82
0
    {
83
0
        Error::from_adhoc(message, backtrace!())
84
0
    }
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error3msgNtNtCsbpSlAbJY2yh_5alloc6string6StringECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error3msgReECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error3msgNtNtCsbpSlAbJY2yh_5alloc6string6StringEB5_
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error3msgReEB5_
85
86
    #[cfg(feature = "std")]
87
    #[cold]
88
5.01k
    pub(crate) fn from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
89
5.01k
    where
90
5.01k
        E: StdError + Send + Sync + 'static,
91
5.01k
    {
92
5.01k
        let vtable = &ErrorVTable {
93
5.01k
            object_drop: object_drop::<E>,
94
5.01k
            object_ref: object_ref::<E>,
95
5.01k
            #[cfg(anyhow_no_ptr_addr_of)]
96
5.01k
            object_mut: object_mut::<E>,
97
5.01k
            object_boxed: object_boxed::<E>,
98
5.01k
            object_downcast: object_downcast::<E>,
99
5.01k
            #[cfg(anyhow_no_ptr_addr_of)]
100
5.01k
            object_downcast_mut: object_downcast_mut::<E>,
101
5.01k
            object_drop_rest: object_drop_front::<E>,
102
5.01k
            #[cfg(all(
103
5.01k
                not(error_generic_member_access),
104
5.01k
                any(std_backtrace, feature = "backtrace")
105
5.01k
            ))]
106
5.01k
            object_backtrace: no_backtrace,
107
5.01k
        };
108
5.01k
109
5.01k
        // Safety: passing vtable that operates on the right type E.
110
5.01k
        unsafe { Error::construct(error, vtable, backtrace) }
111
5.01k
    }
_RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error8from_stdNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Line
Count
Source
88
5.01k
    pub(crate) fn from_std<E>(error: E, backtrace: Option<Backtrace>) -> Self
89
5.01k
    where
90
5.01k
        E: StdError + Send + Sync + 'static,
91
5.01k
    {
92
5.01k
        let vtable = &ErrorVTable {
93
5.01k
            object_drop: object_drop::<E>,
94
5.01k
            object_ref: object_ref::<E>,
95
5.01k
            #[cfg(anyhow_no_ptr_addr_of)]
96
5.01k
            object_mut: object_mut::<E>,
97
5.01k
            object_boxed: object_boxed::<E>,
98
5.01k
            object_downcast: object_downcast::<E>,
99
5.01k
            #[cfg(anyhow_no_ptr_addr_of)]
100
5.01k
            object_downcast_mut: object_downcast_mut::<E>,
101
5.01k
            object_drop_rest: object_drop_front::<E>,
102
5.01k
            #[cfg(all(
103
5.01k
                not(error_generic_member_access),
104
5.01k
                any(std_backtrace, feature = "backtrace")
105
5.01k
            ))]
106
5.01k
            object_backtrace: no_backtrace,
107
5.01k
        };
108
5.01k
109
5.01k
        // Safety: passing vtable that operates on the right type E.
110
5.01k
        unsafe { Error::construct(error, vtable, backtrace) }
111
5.01k
    }
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error8from_stdpEB5_
112
113
    #[cold]
114
0
    pub(crate) fn from_adhoc<M>(message: M, backtrace: Option<Backtrace>) -> Self
115
0
    where
116
0
        M: Display + Debug + Send + Sync + 'static,
117
0
    {
118
0
        use crate::wrapper::MessageError;
119
0
        let error: MessageError<M> = MessageError(message);
120
0
        let vtable = &ErrorVTable {
121
0
            object_drop: object_drop::<MessageError<M>>,
122
0
            object_ref: object_ref::<MessageError<M>>,
123
0
            #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
124
0
            object_mut: object_mut::<MessageError<M>>,
125
0
            object_boxed: object_boxed::<MessageError<M>>,
126
0
            object_downcast: object_downcast::<M>,
127
0
            #[cfg(anyhow_no_ptr_addr_of)]
128
0
            object_downcast_mut: object_downcast_mut::<M>,
129
0
            object_drop_rest: object_drop_front::<M>,
130
0
            #[cfg(all(
131
0
                not(error_generic_member_access),
132
0
                any(std_backtrace, feature = "backtrace")
133
0
            ))]
134
0
            object_backtrace: no_backtrace,
135
0
        };
136
0
137
0
        // Safety: MessageError is repr(transparent) so it is okay for the
138
0
        // vtable to allow casting the MessageError<M> to M.
139
0
        unsafe { Error::construct(error, vtable, backtrace) }
140
0
    }
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error10from_adhocNtNtCsbpSlAbJY2yh_5alloc6string6StringECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error10from_adhocReECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error10from_adhocNtNtCsbpSlAbJY2yh_5alloc6string6StringEB5_
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error10from_adhocReEB5_
141
142
    #[cold]
143
0
    pub(crate) fn from_display<M>(message: M, backtrace: Option<Backtrace>) -> Self
144
0
    where
145
0
        M: Display + Send + Sync + 'static,
146
0
    {
147
0
        use crate::wrapper::DisplayError;
148
0
        let error: DisplayError<M> = DisplayError(message);
149
0
        let vtable = &ErrorVTable {
150
0
            object_drop: object_drop::<DisplayError<M>>,
151
0
            object_ref: object_ref::<DisplayError<M>>,
152
0
            #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
153
0
            object_mut: object_mut::<DisplayError<M>>,
154
0
            object_boxed: object_boxed::<DisplayError<M>>,
155
0
            object_downcast: object_downcast::<M>,
156
0
            #[cfg(anyhow_no_ptr_addr_of)]
157
0
            object_downcast_mut: object_downcast_mut::<M>,
158
0
            object_drop_rest: object_drop_front::<M>,
159
0
            #[cfg(all(
160
0
                not(error_generic_member_access),
161
0
                any(std_backtrace, feature = "backtrace")
162
0
            ))]
163
0
            object_backtrace: no_backtrace,
164
0
        };
165
0
166
0
        // Safety: DisplayError is repr(transparent) so it is okay for the
167
0
        // vtable to allow casting the DisplayError<M> to M.
168
0
        unsafe { Error::construct(error, vtable, backtrace) }
169
0
    }
170
171
    #[cfg(feature = "std")]
172
    #[cold]
173
0
    pub(crate) fn from_context<C, E>(context: C, error: E, backtrace: Option<Backtrace>) -> Self
174
0
    where
175
0
        C: Display + Send + Sync + 'static,
176
0
        E: StdError + Send + Sync + 'static,
177
0
    {
178
0
        let error: ContextError<C, E> = ContextError { context, error };
179
0
180
0
        let vtable = &ErrorVTable {
181
0
            object_drop: object_drop::<ContextError<C, E>>,
182
0
            object_ref: object_ref::<ContextError<C, E>>,
183
0
            #[cfg(anyhow_no_ptr_addr_of)]
184
0
            object_mut: object_mut::<ContextError<C, E>>,
185
0
            object_boxed: object_boxed::<ContextError<C, E>>,
186
0
            object_downcast: context_downcast::<C, E>,
187
0
            #[cfg(anyhow_no_ptr_addr_of)]
188
0
            object_downcast_mut: context_downcast_mut::<C, E>,
189
0
            object_drop_rest: context_drop_rest::<C, E>,
190
0
            #[cfg(all(
191
0
                not(error_generic_member_access),
192
0
                any(std_backtrace, feature = "backtrace")
193
0
            ))]
194
0
            object_backtrace: no_backtrace,
195
0
        };
196
0
197
0
        // Safety: passing vtable that operates on the right type.
198
0
        unsafe { Error::construct(error, vtable, backtrace) }
199
0
    }
200
201
    #[cfg(feature = "std")]
202
    #[cold]
203
0
    pub(crate) fn from_boxed(
204
0
        error: Box<dyn StdError + Send + Sync>,
205
0
        backtrace: Option<Backtrace>,
206
0
    ) -> Self {
207
0
        use crate::wrapper::BoxedError;
208
0
        let error = BoxedError(error);
209
0
        let vtable = &ErrorVTable {
210
0
            object_drop: object_drop::<BoxedError>,
211
0
            object_ref: object_ref::<BoxedError>,
212
0
            #[cfg(anyhow_no_ptr_addr_of)]
213
0
            object_mut: object_mut::<BoxedError>,
214
0
            object_boxed: object_boxed::<BoxedError>,
215
0
            object_downcast: object_downcast::<Box<dyn StdError + Send + Sync>>,
216
0
            #[cfg(anyhow_no_ptr_addr_of)]
217
0
            object_downcast_mut: object_downcast_mut::<Box<dyn StdError + Send + Sync>>,
218
0
            object_drop_rest: object_drop_front::<Box<dyn StdError + Send + Sync>>,
219
0
            #[cfg(all(
220
0
                not(error_generic_member_access),
221
0
                any(std_backtrace, feature = "backtrace")
222
0
            ))]
223
0
            object_backtrace: no_backtrace,
224
0
        };
225
0
226
0
        // Safety: BoxedError is repr(transparent) so it is okay for the vtable
227
0
        // to allow casting to Box<dyn StdError + Send + Sync>.
228
0
        unsafe { Error::construct(error, vtable, backtrace) }
229
0
    }
230
231
    // Takes backtrace as argument rather than capturing it here so that the
232
    // user sees one fewer layer of wrapping noise in the backtrace.
233
    //
234
    // Unsafe because the given vtable must have sensible behavior on the error
235
    // value of type E.
236
    #[cold]
237
5.01k
    unsafe fn construct<E>(
238
5.01k
        error: E,
239
5.01k
        vtable: &'static ErrorVTable,
240
5.01k
        backtrace: Option<Backtrace>,
241
5.01k
    ) -> Self
242
5.01k
    where
243
5.01k
        E: StdError + Send + Sync + 'static,
244
5.01k
    {
245
5.01k
        let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl {
246
5.01k
            vtable,
247
5.01k
            backtrace,
248
5.01k
            _object: error,
249
5.01k
        });
250
5.01k
        // Erase the concrete type of E from the compile-time type system. This
251
5.01k
        // is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to
252
5.01k
        // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the
253
5.01k
        // result is a thin pointer. The necessary behavior for manipulating the
254
5.01k
        // underlying ErrorImpl<E> is preserved in the vtable provided by the
255
5.01k
        // caller rather than a builtin fat pointer vtable.
256
5.01k
        let inner = Own::new(inner).cast::<ErrorImpl>();
257
5.01k
        Error { inner }
258
5.01k
    }
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error9constructINtB3_12ContextErrorReBw_EECs5HNiFFfDLPG_6decode
_RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error9constructNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Line
Count
Source
237
5.01k
    unsafe fn construct<E>(
238
5.01k
        error: E,
239
5.01k
        vtable: &'static ErrorVTable,
240
5.01k
        backtrace: Option<Backtrace>,
241
5.01k
    ) -> Self
242
5.01k
    where
243
5.01k
        E: StdError + Send + Sync + 'static,
244
5.01k
    {
245
5.01k
        let inner: Box<ErrorImpl<E>> = Box::new(ErrorImpl {
246
5.01k
            vtable,
247
5.01k
            backtrace,
248
5.01k
            _object: error,
249
5.01k
        });
250
5.01k
        // Erase the concrete type of E from the compile-time type system. This
251
5.01k
        // is equivalent to the safe unsize coercion from Box<ErrorImpl<E>> to
252
5.01k
        // Box<ErrorImpl<dyn StdError + Send + Sync + 'static>> except that the
253
5.01k
        // result is a thin pointer. The necessary behavior for manipulating the
254
5.01k
        // underlying ErrorImpl<E> is preserved in the vtable provided by the
255
5.01k
        // caller rather than a builtin fat pointer vtable.
256
5.01k
        let inner = Own::new(inner).cast::<ErrorImpl>();
257
5.01k
        Error { inner }
258
5.01k
    }
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error9constructINtNtB5_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error9constructINtNtB5_7wrapper12MessageErrorReEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error9constructINtNtB5_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEB5_
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error9constructINtNtB5_7wrapper12MessageErrorReEEB5_
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error9constructNtNtB5_7wrapper10BoxedErrorEB5_
259
260
    /// Wrap the error value with additional context.
261
    ///
262
    /// For attaching context to a `Result` as it is propagated, the
263
    /// [`Context`][crate::Context] extension trait may be more convenient than
264
    /// this function.
265
    ///
266
    /// The primary reason to use `error.context(...)` instead of
267
    /// `result.context(...)` via the `Context` trait would be if the context
268
    /// needs to depend on some data held by the underlying error:
269
    ///
270
    /// ```
271
    /// # use std::fmt::{self, Debug, Display};
272
    /// #
273
    /// # type T = ();
274
    /// #
275
    /// # impl std::error::Error for ParseError {}
276
    /// # impl Debug for ParseError {
277
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
278
    /// #         unimplemented!()
279
    /// #     }
280
    /// # }
281
    /// # impl Display for ParseError {
282
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
283
    /// #         unimplemented!()
284
    /// #     }
285
    /// # }
286
    /// #
287
    /// use anyhow::Result;
288
    /// use std::fs::File;
289
    /// use std::path::Path;
290
    ///
291
    /// struct ParseError {
292
    ///     line: usize,
293
    ///     column: usize,
294
    /// }
295
    ///
296
    /// fn parse_impl(file: File) -> Result<T, ParseError> {
297
    ///     # const IGNORE: &str = stringify! {
298
    ///     ...
299
    ///     # };
300
    ///     # unimplemented!()
301
    /// }
302
    ///
303
    /// pub fn parse(path: impl AsRef<Path>) -> Result<T> {
304
    ///     let file = File::open(&path)?;
305
    ///     parse_impl(file).map_err(|error| {
306
    ///         let context = format!(
307
    ///             "only the first {} lines of {} are valid",
308
    ///             error.line, path.as_ref().display(),
309
    ///         );
310
    ///         anyhow::Error::new(error).context(context)
311
    ///     })
312
    /// }
313
    /// ```
314
    #[cold]
315
    #[must_use]
316
0
    pub fn context<C>(self, context: C) -> Self
317
0
    where
318
0
        C: Display + Send + Sync + 'static,
319
0
    {
320
0
        let error: ContextError<C, Error> = ContextError {
321
0
            context,
322
0
            error: self,
323
0
        };
324
0
325
0
        let vtable = &ErrorVTable {
326
0
            object_drop: object_drop::<ContextError<C, Error>>,
327
0
            object_ref: object_ref::<ContextError<C, Error>>,
328
0
            #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
329
0
            object_mut: object_mut::<ContextError<C, Error>>,
330
0
            object_boxed: object_boxed::<ContextError<C, Error>>,
331
0
            object_downcast: context_chain_downcast::<C>,
332
0
            #[cfg(anyhow_no_ptr_addr_of)]
333
0
            object_downcast_mut: context_chain_downcast_mut::<C>,
334
0
            object_drop_rest: context_chain_drop_rest::<C>,
335
0
            #[cfg(all(
336
0
                not(error_generic_member_access),
337
0
                any(std_backtrace, feature = "backtrace")
338
0
            ))]
339
0
            object_backtrace: context_backtrace::<C>,
340
0
        };
341
0
342
0
        // As the cause is anyhow::Error, we already have a backtrace for it.
343
0
        let backtrace = None;
344
0
345
0
        // Safety: passing vtable that operates on the right type.
346
0
        unsafe { Error::construct(error, vtable, backtrace) }
347
0
    }
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error7contextReECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error7contextpEB5_
348
349
    /// Get the backtrace for this Error.
350
    ///
351
    /// In order for the backtrace to be meaningful, one of the two environment
352
    /// variables `RUST_LIB_BACKTRACE=1` or `RUST_BACKTRACE=1` must be defined
353
    /// and `RUST_LIB_BACKTRACE` must not be `0`. Backtraces are somewhat
354
    /// expensive to capture in Rust, so we don't necessarily want to be
355
    /// capturing them all over the place all the time.
356
    ///
357
    /// - If you want panics and errors to both have backtraces, set
358
    ///   `RUST_BACKTRACE=1`;
359
    /// - If you want only errors to have backtraces, set
360
    ///   `RUST_LIB_BACKTRACE=1`;
361
    /// - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
362
    ///   `RUST_LIB_BACKTRACE=0`.
363
    ///
364
    /// # Stability
365
    ///
366
    /// Standard library backtraces are only available when using Rust &ge;
367
    /// 1.65. On older compilers, this function is only available if the crate's
368
    /// "backtrace" feature is enabled, and will use the `backtrace` crate as
369
    /// the underlying backtrace implementation. The return type of this
370
    /// function on old compilers is `&(impl Debug + Display)`.
371
    ///
372
    /// ```toml
373
    /// [dependencies]
374
    /// anyhow = { version = "1.0", features = ["backtrace"] }
375
    /// ```
376
    #[cfg(any(std_backtrace, feature = "backtrace"))]
377
0
    pub fn backtrace(&self) -> &impl_backtrace!() {
378
0
        unsafe { ErrorImpl::backtrace(self.inner.by_ref()) }
379
0
    }
380
381
    /// An iterator of the chain of source errors contained by this Error.
382
    ///
383
    /// This iterator will visit every error in the cause chain of this error
384
    /// object, beginning with the error that this error object was created
385
    /// from.
386
    ///
387
    /// # Example
388
    ///
389
    /// ```
390
    /// use anyhow::Error;
391
    /// use std::io;
392
    ///
393
    /// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
394
    ///     for cause in error.chain() {
395
    ///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
396
    ///             return Some(io_error.kind());
397
    ///         }
398
    ///     }
399
    ///     None
400
    /// }
401
    /// ```
402
    #[cfg(feature = "std")]
403
    #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
404
    #[cold]
405
0
    pub fn chain(&self) -> Chain {
406
0
        unsafe { ErrorImpl::chain(self.inner.by_ref()) }
407
0
    }
408
409
    /// The lowest level cause of this error &mdash; this error's cause's
410
    /// cause's cause etc.
411
    ///
412
    /// The root cause is the last error in the iterator produced by
413
    /// [`chain()`][Error::chain].
414
    #[cfg(feature = "std")]
415
    #[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
416
0
    pub fn root_cause(&self) -> &(dyn StdError + 'static) {
417
0
        self.chain().last().unwrap()
418
0
    }
419
420
    /// Returns true if `E` is the type held by this error object.
421
    ///
422
    /// For errors with context, this method returns true if `E` matches the
423
    /// type of the context `C` **or** the type of the error on which the
424
    /// context has been attached. For details about the interaction between
425
    /// context and downcasting, [see here].
426
    ///
427
    /// [see here]: trait.Context.html#effect-on-downcasting
428
0
    pub fn is<E>(&self) -> bool
429
0
    where
430
0
        E: Display + Debug + Send + Sync + 'static,
431
0
    {
432
0
        self.downcast_ref::<E>().is_some()
433
0
    }
434
435
    /// Attempt to downcast the error object to a concrete type.
436
0
    pub fn downcast<E>(mut self) -> Result<E, Self>
437
0
    where
438
0
        E: Display + Debug + Send + Sync + 'static,
439
0
    {
440
0
        let target = TypeId::of::<E>();
441
0
        let inner = self.inner.by_mut();
442
        unsafe {
443
            // Use vtable to find NonNull<()> which points to a value of type E
444
            // somewhere inside the data structure.
445
            #[cfg(not(anyhow_no_ptr_addr_of))]
446
0
            let addr = match (vtable(inner.ptr).object_downcast)(inner.by_ref(), target) {
447
0
                Some(addr) => addr.by_mut().extend(),
448
0
                None => return Err(self),
449
            };
450
            #[cfg(anyhow_no_ptr_addr_of)]
451
            let addr = match (vtable(inner.ptr).object_downcast_mut)(inner, target) {
452
                Some(addr) => addr.extend(),
453
                None => return Err(self),
454
            };
455
456
            // Prepare to read E out of the data structure. We'll drop the rest
457
            // of the data structure separately so that E is not dropped.
458
0
            let outer = ManuallyDrop::new(self);
459
0
460
0
            // Read E from where the vtable found it.
461
0
            let error = addr.cast::<E>().read();
462
0
463
0
            // Drop rest of the data structure outside of E.
464
0
            (vtable(outer.inner.ptr).object_drop_rest)(outer.inner, target);
465
0
466
0
            Ok(error)
467
        }
468
0
    }
469
470
    /// Downcast this error object by reference.
471
    ///
472
    /// # Example
473
    ///
474
    /// ```
475
    /// # use anyhow::anyhow;
476
    /// # use std::fmt::{self, Display};
477
    /// # use std::task::Poll;
478
    /// #
479
    /// # #[derive(Debug)]
480
    /// # enum DataStoreError {
481
    /// #     Censored(()),
482
    /// # }
483
    /// #
484
    /// # impl Display for DataStoreError {
485
    /// #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
486
    /// #         unimplemented!()
487
    /// #     }
488
    /// # }
489
    /// #
490
    /// # impl std::error::Error for DataStoreError {}
491
    /// #
492
    /// # const REDACTED_CONTENT: () = ();
493
    /// #
494
    /// # let error = anyhow!("...");
495
    /// # let root_cause = &error;
496
    /// #
497
    /// # let ret =
498
    /// // If the error was caused by redaction, then return a tombstone instead
499
    /// // of the content.
500
    /// match root_cause.downcast_ref::<DataStoreError>() {
501
    ///     Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
502
    ///     None => Err(error),
503
    /// }
504
    /// # ;
505
    /// ```
506
5.01k
    pub fn downcast_ref<E>(&self) -> Option<&E>
507
5.01k
    where
508
5.01k
        E: Display + Debug + Send + Sync + 'static,
509
5.01k
    {
510
5.01k
        let target = TypeId::of::<E>();
511
        unsafe {
512
            // Use vtable to find NonNull<()> which points to a value of type E
513
            // somewhere inside the data structure.
514
5.01k
            let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
515
5.01k
            Some(addr.cast::<E>().deref())
516
        }
517
5.01k
    }
_RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error12downcast_refNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Line
Count
Source
506
5.01k
    pub fn downcast_ref<E>(&self) -> Option<&E>
507
5.01k
    where
508
5.01k
        E: Display + Debug + Send + Sync + 'static,
509
5.01k
    {
510
5.01k
        let target = TypeId::of::<E>();
511
        unsafe {
512
            // Use vtable to find NonNull<()> which points to a value of type E
513
            // somewhere inside the data structure.
514
5.01k
            let addr = (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?;
515
5.01k
            Some(addr.cast::<E>().deref())
516
        }
517
5.01k
    }
Unexecuted instantiation: _RINvMNtCskkyJyiFoyZJ_6anyhow5errorNtB5_5Error12downcast_refpEB5_
518
519
    /// Downcast this error object by mutable reference.
520
0
    pub fn downcast_mut<E>(&mut self) -> Option<&mut E>
521
0
    where
522
0
        E: Display + Debug + Send + Sync + 'static,
523
0
    {
524
0
        let target = TypeId::of::<E>();
525
        unsafe {
526
            // Use vtable to find NonNull<()> which points to a value of type E
527
            // somewhere inside the data structure.
528
529
            #[cfg(not(anyhow_no_ptr_addr_of))]
530
0
            let addr =
531
0
                (vtable(self.inner.ptr).object_downcast)(self.inner.by_ref(), target)?.by_mut();
532
0
533
0
            #[cfg(anyhow_no_ptr_addr_of)]
534
0
            let addr = (vtable(self.inner.ptr).object_downcast_mut)(self.inner.by_mut(), target)?;
535
0
536
0
            Some(addr.cast::<E>().deref_mut())
537
        }
538
0
    }
539
540
    #[cfg(error_generic_member_access)]
541
0
    pub(crate) fn provide<'a>(&'a self, request: &mut Request<'a>) {
542
0
        unsafe { ErrorImpl::provide(self.inner.by_ref(), request) }
543
0
    }
544
545
    // Called by thiserror when you have `#[source] anyhow::Error`. This provide
546
    // implementation includes the anyhow::Error's Backtrace if any, unlike
547
    // deref'ing to dyn Error where the provide implementation would include
548
    // only the original error's Backtrace from before it got wrapped into an
549
    // anyhow::Error.
550
    #[cfg(error_generic_member_access)]
551
    #[doc(hidden)]
552
0
    pub fn thiserror_provide<'a>(&'a self, request: &mut Request<'a>) {
553
0
        Self::provide(self, request);
554
0
    }
555
}
556
557
#[cfg(feature = "std")]
558
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
559
impl<E> From<E> for Error
560
where
561
    E: StdError + Send + Sync + 'static,
562
{
563
    #[cold]
564
5.01k
    fn from(error: E) -> Self {
565
5.01k
        let backtrace = backtrace_if_absent!(&error);
566
5.01k
        Error::from_std(error, backtrace)
567
5.01k
    }
_RNvXs_NtCskkyJyiFoyZJ_6anyhow5errorNtB6_5ErrorINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorE4fromCs5HNiFFfDLPG_6decode
Line
Count
Source
564
5.01k
    fn from(error: E) -> Self {
565
5.01k
        let backtrace = backtrace_if_absent!(&error);
566
5.01k
        Error::from_std(error, backtrace)
567
5.01k
    }
Unexecuted instantiation: _RNvXININtCskkyJyiFoyZJ_6anyhow5errors_0pENtB7_5ErrorINtNtCs1ujR1JRCAmI_4core7convert4FrompE4fromB7_
568
}
569
570
#[cfg(feature = "std")]
571
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
572
impl Deref for Error {
573
    type Target = dyn StdError + Send + Sync + 'static;
574
575
0
    fn deref(&self) -> &Self::Target {
576
0
        unsafe { ErrorImpl::error(self.inner.by_ref()) }
577
0
    }
578
}
579
580
#[cfg(feature = "std")]
581
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
582
impl DerefMut for Error {
583
0
    fn deref_mut(&mut self) -> &mut Self::Target {
584
0
        unsafe { ErrorImpl::error_mut(self.inner.by_mut()) }
585
0
    }
586
}
587
588
impl Display for Error {
589
0
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
590
0
        unsafe { ErrorImpl::display(self.inner.by_ref(), formatter) }
591
0
    }
592
}
593
594
impl Debug for Error {
595
0
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
596
0
        unsafe { ErrorImpl::debug(self.inner.by_ref(), formatter) }
597
0
    }
598
}
599
600
impl Drop for Error {
601
5.01k
    fn drop(&mut self) {
602
5.01k
        unsafe {
603
5.01k
            // Invoke the vtable's drop behavior.
604
5.01k
            (vtable(self.inner.ptr).object_drop)(self.inner);
605
5.01k
        }
606
5.01k
    }
607
}
608
609
struct ErrorVTable {
610
    object_drop: unsafe fn(Own<ErrorImpl>),
611
    object_ref: unsafe fn(Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>,
612
    #[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
613
    object_mut: unsafe fn(Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static),
614
    object_boxed: unsafe fn(Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>,
615
    object_downcast: unsafe fn(Ref<ErrorImpl>, TypeId) -> Option<Ref<()>>,
616
    #[cfg(anyhow_no_ptr_addr_of)]
617
    object_downcast_mut: unsafe fn(Mut<ErrorImpl>, TypeId) -> Option<Mut<()>>,
618
    object_drop_rest: unsafe fn(Own<ErrorImpl>, TypeId),
619
    #[cfg(all(
620
        not(error_generic_member_access),
621
        any(std_backtrace, feature = "backtrace")
622
    ))]
623
    object_backtrace: unsafe fn(Ref<ErrorImpl>) -> Option<&Backtrace>,
624
}
625
626
// Safety: requires layout of *e to match ErrorImpl<E>.
627
5.01k
unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
628
5.01k
    // Cast back to ErrorImpl<E> so that the allocator receives the correct
629
5.01k
    // Layout to deallocate the Box's memory.
630
5.01k
    let unerased_own = e.cast::<ErrorImpl<E>>();
631
5.01k
    drop(unsafe { unerased_own.boxed() });
632
5.01k
}
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error11object_dropINtB2_12ContextErrorReNtB4_5ErrorEECs5HNiFFfDLPG_6decode
_RINvNtCskkyJyiFoyZJ_6anyhow5error11object_dropNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Line
Count
Source
627
5.01k
unsafe fn object_drop<E>(e: Own<ErrorImpl>) {
628
5.01k
    // Cast back to ErrorImpl<E> so that the allocator receives the correct
629
5.01k
    // Layout to deallocate the Box's memory.
630
5.01k
    let unerased_own = e.cast::<ErrorImpl<E>>();
631
5.01k
    drop(unsafe { unerased_own.boxed() });
632
5.01k
}
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error11object_dropINtNtB4_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error11object_dropINtNtB4_7wrapper12MessageErrorReEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error11object_dropINtNtB4_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error11object_dropINtNtB4_7wrapper12MessageErrorReEEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error11object_dropNtNtB4_7wrapper10BoxedErrorEB4_
633
634
// Safety: requires layout of *e to match ErrorImpl<E>.
635
0
unsafe fn object_drop_front<E>(e: Own<ErrorImpl>, target: TypeId) {
636
0
    // Drop the fields of ErrorImpl other than E as well as the Box allocation,
637
0
    // without dropping E itself. This is used by downcast after doing a
638
0
    // ptr::read to take ownership of the E.
639
0
    let _ = target;
640
0
    let unerased_own = e.cast::<ErrorImpl<ManuallyDrop<E>>>();
641
0
    drop(unsafe { unerased_own.boxed() });
642
0
}
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error17object_drop_frontNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error17object_drop_frontNtNtCsbpSlAbJY2yh_5alloc6string6StringECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error17object_drop_frontReECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error17object_drop_frontINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtB1s_6marker4SendNtB1Z_4SyncEL_EEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error17object_drop_frontNtNtCsbpSlAbJY2yh_5alloc6string6StringEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error17object_drop_frontReEB4_
643
644
// Safety: requires layout of *e to match ErrorImpl<E>.
645
0
unsafe fn object_ref<E>(e: Ref<ErrorImpl>) -> Ref<dyn StdError + Send + Sync + 'static>
646
0
where
647
0
    E: StdError + Send + Sync + 'static,
648
0
{
649
0
    // Attach E's native StdError vtable onto a pointer to self._object.
650
0
651
0
    let unerased_ref = e.cast::<ErrorImpl<E>>();
652
0
653
0
    #[cfg(not(anyhow_no_ptr_addr_of))]
654
0
    return Ref::from_raw(unsafe {
655
0
        NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E)
656
0
    });
657
0
658
0
    #[cfg(anyhow_no_ptr_addr_of)]
659
0
    return Ref::new(unsafe { &unerased_ref.deref()._object });
660
0
}
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error10object_refINtB2_12ContextErrorReNtB4_5ErrorEECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error10object_refNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error10object_refINtNtB4_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error10object_refINtNtB4_7wrapper12MessageErrorReEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error10object_refINtNtB4_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error10object_refINtNtB4_7wrapper12MessageErrorReEEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error10object_refNtNtB4_7wrapper10BoxedErrorEB4_
661
662
// Safety: requires layout of *e to match ErrorImpl<E>, and for `e` to be derived
663
// from a `&mut`
664
#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
665
unsafe fn object_mut<E>(e: Mut<ErrorImpl>) -> &mut (dyn StdError + Send + Sync + 'static)
666
where
667
    E: StdError + Send + Sync + 'static,
668
{
669
    // Attach E's native StdError vtable onto a pointer to self._object.
670
    let unerased_mut = e.cast::<ErrorImpl<E>>();
671
    unsafe { &mut unerased_mut.deref_mut()._object }
672
}
673
674
// Safety: requires layout of *e to match ErrorImpl<E>.
675
0
unsafe fn object_boxed<E>(e: Own<ErrorImpl>) -> Box<dyn StdError + Send + Sync + 'static>
676
0
where
677
0
    E: StdError + Send + Sync + 'static,
678
0
{
679
0
    // Attach ErrorImpl<E>'s native StdError vtable. The StdError impl is below.
680
0
    let unerased_own = e.cast::<ErrorImpl<E>>();
681
0
    unsafe { unerased_own.boxed() }
682
0
}
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error12object_boxedINtB2_12ContextErrorReNtB4_5ErrorEECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error12object_boxedNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error12object_boxedINtNtB4_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error12object_boxedINtNtB4_7wrapper12MessageErrorReEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error12object_boxedINtNtB4_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error12object_boxedINtNtB4_7wrapper12MessageErrorReEEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error12object_boxedNtNtB4_7wrapper10BoxedErrorEB4_
683
684
// Safety: requires layout of *e to match ErrorImpl<E>.
685
5.01k
unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
686
5.01k
where
687
5.01k
    E: 'static,
688
5.01k
{
689
5.01k
    if TypeId::of::<E>() == target {
690
        // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
691
        // pointer to its E field.
692
693
5.01k
        let unerased_ref = e.cast::<ErrorImpl<E>>();
694
5.01k
695
5.01k
        #[cfg(not(anyhow_no_ptr_addr_of))]
696
5.01k
        return Some(
697
5.01k
            Ref::from_raw(unsafe {
698
5.01k
                NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E)
699
5.01k
            })
700
5.01k
            .cast::<()>(),
701
5.01k
        );
702
703
        #[cfg(anyhow_no_ptr_addr_of)]
704
        return Some(Ref::new(unsafe { &unerased_ref.deref()._object }).cast::<()>());
705
    } else {
706
0
        None
707
    }
708
5.01k
}
_RINvNtCskkyJyiFoyZJ_6anyhow5error15object_downcastNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Line
Count
Source
685
5.01k
unsafe fn object_downcast<E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
686
5.01k
where
687
5.01k
    E: 'static,
688
5.01k
{
689
5.01k
    if TypeId::of::<E>() == target {
690
        // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
691
        // pointer to its E field.
692
693
5.01k
        let unerased_ref = e.cast::<ErrorImpl<E>>();
694
5.01k
695
5.01k
        #[cfg(not(anyhow_no_ptr_addr_of))]
696
5.01k
        return Some(
697
5.01k
            Ref::from_raw(unsafe {
698
5.01k
                NonNull::new_unchecked(ptr::addr_of!((*unerased_ref.as_ptr())._object) as *mut E)
699
5.01k
            })
700
5.01k
            .cast::<()>(),
701
5.01k
        );
702
703
        #[cfg(anyhow_no_ptr_addr_of)]
704
        return Some(Ref::new(unsafe { &unerased_ref.deref()._object }).cast::<()>());
705
    } else {
706
0
        None
707
    }
708
5.01k
}
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error15object_downcastNtNtCsbpSlAbJY2yh_5alloc6string6StringECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error15object_downcastReECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error15object_downcastINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtB1q_6marker4SendNtB1X_4SyncEL_EEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error15object_downcastNtNtCsbpSlAbJY2yh_5alloc6string6StringEB4_
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error15object_downcastReEB4_
709
710
// Safety: requires layout of *e to match ErrorImpl<E>.
711
#[cfg(anyhow_no_ptr_addr_of)]
712
unsafe fn object_downcast_mut<E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
713
where
714
    E: 'static,
715
{
716
    if TypeId::of::<E>() == target {
717
        // Caller is looking for an E pointer and e is ErrorImpl<E>, take a
718
        // pointer to its E field.
719
        let unerased_mut = e.cast::<ErrorImpl<E>>();
720
        let unerased = unsafe { unerased_mut.deref_mut() };
721
        Some(Mut::new(&mut unerased._object).cast::<()>())
722
    } else {
723
        None
724
    }
725
}
726
727
#[cfg(all(
728
    not(error_generic_member_access),
729
    any(std_backtrace, feature = "backtrace")
730
))]
731
fn no_backtrace(e: Ref<ErrorImpl>) -> Option<&Backtrace> {
732
    let _ = e;
733
    None
734
}
735
736
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
737
#[cfg(feature = "std")]
738
0
unsafe fn context_downcast<C, E>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
739
0
where
740
0
    C: 'static,
741
0
    E: 'static,
742
0
{
743
0
    if TypeId::of::<C>() == target {
744
0
        let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
745
0
        let unerased = unsafe { unerased_ref.deref() };
746
0
        Some(Ref::new(&unerased._object.context).cast::<()>())
747
0
    } else if TypeId::of::<E>() == target {
748
0
        let unerased_ref = e.cast::<ErrorImpl<ContextError<C, E>>>();
749
0
        let unerased = unsafe { unerased_ref.deref() };
750
0
        Some(Ref::new(&unerased._object.error).cast::<()>())
751
    } else {
752
0
        None
753
    }
754
0
}
755
756
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
757
#[cfg(all(feature = "std", anyhow_no_ptr_addr_of))]
758
unsafe fn context_downcast_mut<C, E>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
759
where
760
    C: 'static,
761
    E: 'static,
762
{
763
    if TypeId::of::<C>() == target {
764
        let unerased_mut = e.cast::<ErrorImpl<ContextError<C, E>>>();
765
        let unerased = unsafe { unerased_mut.deref_mut() };
766
        Some(Mut::new(&mut unerased._object.context).cast::<()>())
767
    } else if TypeId::of::<E>() == target {
768
        let unerased_mut = e.cast::<ErrorImpl<ContextError<C, E>>>();
769
        let unerased = unsafe { unerased_mut.deref_mut() };
770
        Some(Mut::new(&mut unerased._object.error).cast::<()>())
771
    } else {
772
        None
773
    }
774
}
775
776
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, E>>.
777
#[cfg(feature = "std")]
778
0
unsafe fn context_drop_rest<C, E>(e: Own<ErrorImpl>, target: TypeId)
779
0
where
780
0
    C: 'static,
781
0
    E: 'static,
782
0
{
783
0
    // Called after downcasting by value to either the C or the E and doing a
784
0
    // ptr::read to take ownership of that value.
785
0
    if TypeId::of::<C>() == target {
786
0
        let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, E>>>();
787
0
        drop(unsafe { unerased_own.boxed() });
788
0
    } else {
789
0
        let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<E>>>>();
790
0
        drop(unsafe { unerased_own.boxed() });
791
0
    }
792
0
}
793
794
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
795
0
unsafe fn context_chain_downcast<C>(e: Ref<ErrorImpl>, target: TypeId) -> Option<Ref<()>>
796
0
where
797
0
    C: 'static,
798
0
{
799
0
    let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
800
0
    let unerased = unsafe { unerased_ref.deref() };
801
0
    if TypeId::of::<C>() == target {
802
0
        Some(Ref::new(&unerased._object.context).cast::<()>())
803
    } else {
804
        // Recurse down the context chain per the inner error's vtable.
805
0
        let source = &unerased._object.error;
806
0
        unsafe { (vtable(source.inner.ptr).object_downcast)(source.inner.by_ref(), target) }
807
    }
808
0
}
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error22context_chain_downcastReECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error22context_chain_downcastpEB4_
809
810
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
811
#[cfg(anyhow_no_ptr_addr_of)]
812
unsafe fn context_chain_downcast_mut<C>(e: Mut<ErrorImpl>, target: TypeId) -> Option<Mut<()>>
813
where
814
    C: 'static,
815
{
816
    let unerased_mut = e.cast::<ErrorImpl<ContextError<C, Error>>>();
817
    let unerased = unsafe { unerased_mut.deref_mut() };
818
    if TypeId::of::<C>() == target {
819
        Some(Mut::new(&mut unerased._object.context).cast::<()>())
820
    } else {
821
        // Recurse down the context chain per the inner error's vtable.
822
        let source = &mut unerased._object.error;
823
        unsafe { (vtable(source.inner.ptr).object_downcast_mut)(source.inner.by_mut(), target) }
824
    }
825
}
826
827
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
828
0
unsafe fn context_chain_drop_rest<C>(e: Own<ErrorImpl>, target: TypeId)
829
0
where
830
0
    C: 'static,
831
0
{
832
0
    // Called after downcasting by value to either the C or one of the causes
833
0
    // and doing a ptr::read to take ownership of that value.
834
0
    if TypeId::of::<C>() == target {
835
0
        let unerased_own = e.cast::<ErrorImpl<ContextError<ManuallyDrop<C>, Error>>>();
836
0
        // Drop the entire rest of the data structure rooted in the next Error.
837
0
        drop(unsafe { unerased_own.boxed() });
838
0
    } else {
839
0
        let unerased_own = e.cast::<ErrorImpl<ContextError<C, ManuallyDrop<Error>>>>();
840
0
        let unerased = unsafe { unerased_own.boxed() };
841
0
        // Read the Own<ErrorImpl> from the next error.
842
0
        let inner = unerased._object.error.inner;
843
0
        drop(unerased);
844
0
        let vtable = unsafe { vtable(inner.ptr) };
845
0
        // Recursively drop the next error using the same target typeid.
846
0
        unsafe { (vtable.object_drop_rest)(inner, target) };
847
0
    }
848
0
}
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error23context_chain_drop_restReECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvNtCskkyJyiFoyZJ_6anyhow5error23context_chain_drop_restpEB4_
849
850
// Safety: requires layout of *e to match ErrorImpl<ContextError<C, Error>>.
851
#[cfg(all(
852
    not(error_generic_member_access),
853
    any(std_backtrace, feature = "backtrace")
854
))]
855
#[allow(clippy::unnecessary_wraps)]
856
unsafe fn context_backtrace<C>(e: Ref<ErrorImpl>) -> Option<&Backtrace>
857
where
858
    C: 'static,
859
{
860
    let unerased_ref = e.cast::<ErrorImpl<ContextError<C, Error>>>();
861
    let unerased = unsafe { unerased_ref.deref() };
862
    let backtrace = unsafe { ErrorImpl::backtrace(unerased._object.error.inner.by_ref()) };
863
    Some(backtrace)
864
}
865
866
// NOTE: If working with `ErrorImpl<()>`, references should be avoided in favor
867
// of raw pointers and `NonNull`.
868
// repr C to ensure that E remains in the final position.
869
#[repr(C)]
870
pub(crate) struct ErrorImpl<E = ()> {
871
    vtable: &'static ErrorVTable,
872
    backtrace: Option<Backtrace>,
873
    // NOTE: Don't use directly. Use only through vtable. Erased type may have
874
    // different alignment.
875
    _object: E,
876
}
877
878
// Reads the vtable out of `p`. This is the same as `p.as_ref().vtable`, but
879
// avoids converting `p` into a reference.
880
10.0k
unsafe fn vtable(p: NonNull<ErrorImpl>) -> &'static ErrorVTable {
881
10.0k
    // NOTE: This assumes that `ErrorVTable` is the first field of ErrorImpl.
882
10.0k
    unsafe { *(p.as_ptr() as *const &'static ErrorVTable) }
883
10.0k
}
884
885
// repr C to ensure that ContextError<C, E> has the same layout as
886
// ContextError<ManuallyDrop<C>, E> and ContextError<C, ManuallyDrop<E>>.
887
#[repr(C)]
888
pub(crate) struct ContextError<C, E> {
889
    pub context: C,
890
    pub error: E,
891
}
892
893
impl<E> ErrorImpl<E> {
894
0
    fn erase(&self) -> Ref<ErrorImpl> {
895
0
        // Erase the concrete type of E but preserve the vtable in self.vtable
896
0
        // for manipulating the resulting thin pointer. This is analogous to an
897
0
        // unsize coercion.
898
0
        Ref::new(self).cast::<ErrorImpl>()
899
0
    }
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtB5_12ContextErrorReNtB7_5ErrorEE5eraseCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorE5eraseCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEE5eraseCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEE5eraseCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEE5eraseB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEE5eraseB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtB7_7wrapper10BoxedErrorE5eraseB7_
900
}
901
902
impl ErrorImpl {
903
0
    pub(crate) unsafe fn error(this: Ref<Self>) -> &(dyn StdError + Send + Sync + 'static) {
904
0
        // Use vtable to attach E's native StdError vtable for the right
905
0
        // original type E.
906
0
        unsafe { (vtable(this.ptr).object_ref)(this).deref() }
907
0
    }
908
909
    #[cfg(feature = "std")]
910
0
    pub(crate) unsafe fn error_mut(this: Mut<Self>) -> &mut (dyn StdError + Send + Sync + 'static) {
911
0
        // Use vtable to attach E's native StdError vtable for the right
912
0
        // original type E.
913
0
914
0
        #[cfg(not(anyhow_no_ptr_addr_of))]
915
0
        return unsafe {
916
0
            (vtable(this.ptr).object_ref)(this.by_ref())
917
0
                .by_mut()
918
0
                .deref_mut()
919
0
        };
920
0
921
0
        #[cfg(anyhow_no_ptr_addr_of)]
922
0
        return unsafe { (vtable(this.ptr).object_mut)(this) };
923
0
    }
924
925
    #[cfg(any(std_backtrace, feature = "backtrace"))]
926
0
    pub(crate) unsafe fn backtrace(this: Ref<Self>) -> &Backtrace {
927
0
        // This unwrap can only panic if the underlying error's backtrace method
928
0
        // is nondeterministic, which would only happen in maliciously
929
0
        // constructed code.
930
0
        unsafe { this.deref() }
931
0
            .backtrace
932
0
            .as_ref()
933
0
            .or_else(|| {
934
0
                #[cfg(error_generic_member_access)]
935
0
                return error::request_ref::<Backtrace>(unsafe { Self::error(this) });
936
0
                #[cfg(not(error_generic_member_access))]
937
0
                return unsafe { (vtable(this.ptr).object_backtrace)(this) };
938
0
            })
939
0
            .expect("backtrace capture failed")
940
0
    }
941
942
    #[cfg(error_generic_member_access)]
943
0
    unsafe fn provide<'a>(this: Ref<'a, Self>, request: &mut Request<'a>) {
944
0
        if let Some(backtrace) = unsafe { &this.deref().backtrace } {
945
0
            request.provide_ref(backtrace);
946
0
        }
947
0
        unsafe { Self::error(this) }.provide(request);
948
0
    }
949
950
    #[cold]
951
0
    pub(crate) unsafe fn chain(this: Ref<Self>) -> Chain {
952
0
        Chain::new(unsafe { Self::error(this) })
953
0
    }
954
}
955
956
impl<E> StdError for ErrorImpl<E>
957
where
958
    E: StdError,
959
{
960
0
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
961
0
        unsafe { ErrorImpl::error(self.erase()).source() }
962
0
    }
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtB5_12ContextErrorReNtB7_5ErrorEENtNtCs1ujR1JRCAmI_4core5error5Error6sourceCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorENtNtCs1ujR1JRCAmI_4core5error5Error6sourceCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEENtNtCs1ujR1JRCAmI_4core5error5Error6sourceCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEENtNtCs1ujR1JRCAmI_4core5error5Error6sourceCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEENtNtCs1ujR1JRCAmI_4core5error5Error6sourceB7_
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEENtNtCs1ujR1JRCAmI_4core5error5Error6sourceB7_
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtB7_7wrapper10BoxedErrorENtNtCs1ujR1JRCAmI_4core5error5Error6sourceB7_
963
964
    #[cfg(error_generic_member_access)]
965
0
    fn provide<'a>(&'a self, request: &mut Request<'a>) {
966
0
        unsafe { ErrorImpl::provide(self.erase(), request) }
967
0
    }
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtB5_12ContextErrorReNtB7_5ErrorEENtNtCs1ujR1JRCAmI_4core5error5Error7provideCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorENtNtCs1ujR1JRCAmI_4core5error5Error7provideCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEENtNtCs1ujR1JRCAmI_4core5error5Error7provideCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEENtNtCs1ujR1JRCAmI_4core5error5Error7provideCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEENtNtCs1ujR1JRCAmI_4core5error5Error7provideB7_
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEENtNtCs1ujR1JRCAmI_4core5error5Error7provideB7_
Unexecuted instantiation: _RNvXs7_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtB7_7wrapper10BoxedErrorENtNtCs1ujR1JRCAmI_4core5error5Error7provideB7_
968
}
969
970
impl<E> Debug for ErrorImpl<E>
971
where
972
    E: Debug,
973
{
974
0
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
975
0
        unsafe { ErrorImpl::debug(self.erase(), formatter) }
976
0
    }
Unexecuted instantiation: _RNvXs8_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtB5_12ContextErrorReNtB7_5ErrorEENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXs8_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXs8_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs8_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs8_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtB7_
Unexecuted instantiation: _RNvXs8_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtB7_
Unexecuted instantiation: _RNvXs8_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtB7_7wrapper10BoxedErrorENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtB7_
977
}
978
979
impl<E> Display for ErrorImpl<E>
980
where
981
    E: Display,
982
{
983
0
    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
984
0
        unsafe { Display::fmt(ErrorImpl::error(self.erase()), formatter) }
985
0
    }
Unexecuted instantiation: _RNvXs9_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtB5_12ContextErrorReNtB7_5ErrorEENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXs9_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXs9_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs9_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs9_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtB7_
Unexecuted instantiation: _RNvXs9_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplINtNtB7_7wrapper12MessageErrorReEENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtB7_
Unexecuted instantiation: _RNvXs9_NtCskkyJyiFoyZJ_6anyhow5errorINtB5_9ErrorImplNtNtB7_7wrapper10BoxedErrorENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtB7_
986
}
987
988
impl From<Error> for Box<dyn StdError + Send + Sync + 'static> {
989
    #[cold]
990
0
    fn from(error: Error) -> Self {
991
0
        let outer = ManuallyDrop::new(error);
992
0
        unsafe {
993
0
            // Use vtable to attach ErrorImpl<E>'s native StdError vtable for
994
0
            // the right original type E.
995
0
            (vtable(outer.inner.ptr).object_boxed)(outer.inner)
996
0
        }
997
0
    }
998
}
999
1000
impl From<Error> for Box<dyn StdError + Send + 'static> {
1001
0
    fn from(error: Error) -> Self {
1002
0
        Box::<dyn StdError + Send + Sync>::from(error)
1003
0
    }
1004
}
1005
1006
impl From<Error> for Box<dyn StdError + 'static> {
1007
0
    fn from(error: Error) -> Self {
1008
0
        Box::<dyn StdError + Send + Sync>::from(error)
1009
0
    }
1010
}
1011
1012
#[cfg(feature = "std")]
1013
impl AsRef<dyn StdError + Send + Sync> for Error {
1014
0
    fn as_ref(&self) -> &(dyn StdError + Send + Sync + 'static) {
1015
0
        &**self
1016
0
    }
1017
}
1018
1019
#[cfg(feature = "std")]
1020
impl AsRef<dyn StdError> for Error {
1021
0
    fn as_ref(&self) -> &(dyn StdError + 'static) {
1022
0
        &**self
1023
0
    }
1024
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/fmt.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::chain::Chain;
2
use crate::error::ErrorImpl;
3
use crate::ptr::Ref;
4
use core::fmt::{self, Debug, Write};
5
6
impl ErrorImpl {
7
0
    pub(crate) unsafe fn display(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
8
0
        write!(f, "{}", unsafe { Self::error(this) })?;
9
10
0
        if f.alternate() {
11
0
            let chain = unsafe { Self::chain(this) };
12
0
            for cause in chain.skip(1) {
13
0
                write!(f, ": {}", cause)?;
14
            }
15
0
        }
16
17
0
        Ok(())
18
0
    }
19
20
0
    pub(crate) unsafe fn debug(this: Ref<Self>, f: &mut fmt::Formatter) -> fmt::Result {
21
0
        let error = unsafe { Self::error(this) };
22
0
23
0
        if f.alternate() {
24
0
            return Debug::fmt(error, f);
25
0
        }
26
0
27
0
        write!(f, "{}", error)?;
28
29
0
        if let Some(cause) = error.source() {
30
0
            write!(f, "\n\nCaused by:")?;
31
0
            let multiple = cause.source().is_some();
32
0
            for (n, error) in Chain::new(cause).enumerate() {
33
0
                writeln!(f)?;
34
0
                let mut indented = Indented {
35
0
                    inner: f,
36
0
                    number: if multiple { Some(n) } else { None },
37
                    started: false,
38
                };
39
0
                write!(indented, "{}", error)?;
40
            }
41
0
        }
42
43
        #[cfg(any(std_backtrace, feature = "backtrace"))]
44
        {
45
            use crate::backtrace::BacktraceStatus;
46
            use alloc::string::ToString;
47
48
0
            let backtrace = unsafe { Self::backtrace(this) };
49
0
            if let BacktraceStatus::Captured = backtrace.status() {
50
0
                let mut backtrace = backtrace.to_string();
51
0
                write!(f, "\n\n")?;
52
0
                if backtrace.starts_with("stack backtrace:") {
53
0
                    // Capitalize to match "Caused by:"
54
0
                    backtrace.replace_range(0..1, "S");
55
0
                } else {
56
                    // "stack backtrace:" prefix was removed in
57
                    // https://github.com/rust-lang/backtrace-rs/pull/286
58
0
                    writeln!(f, "Stack backtrace:")?;
59
                }
60
0
                backtrace.truncate(backtrace.trim_end().len());
61
0
                write!(f, "{}", backtrace)?;
62
0
            }
63
        }
64
65
0
        Ok(())
66
0
    }
67
}
68
69
struct Indented<'a, D> {
70
    inner: &'a mut D,
71
    number: Option<usize>,
72
    started: bool,
73
}
74
75
impl<T> Write for Indented<'_, T>
76
where
77
    T: Write,
78
{
79
0
    fn write_str(&mut self, s: &str) -> fmt::Result {
80
0
        for (i, line) in s.split('\n').enumerate() {
81
0
            if !self.started {
82
0
                self.started = true;
83
0
                match self.number {
84
0
                    Some(number) => write!(self.inner, "{: >5}: ", number)?,
85
0
                    None => self.inner.write_str("    ")?,
86
                }
87
0
            } else if i > 0 {
88
0
                self.inner.write_char('\n')?;
89
0
                if self.number.is_some() {
90
0
                    self.inner.write_str("       ")?;
91
                } else {
92
0
                    self.inner.write_str("    ")?;
93
                }
94
0
            }
95
96
0
            self.inner.write_str(line)?;
97
        }
98
99
0
        Ok(())
100
0
    }
101
}
102
103
#[cfg(test)]
104
mod tests {
105
    use super::*;
106
    use alloc::string::String;
107
108
    #[test]
109
    fn one_digit() {
110
        let input = "verify\nthis";
111
        let expected = "    2: verify\n       this";
112
        let mut output = String::new();
113
114
        Indented {
115
            inner: &mut output,
116
            number: Some(2),
117
            started: false,
118
        }
119
        .write_str(input)
120
        .unwrap();
121
122
        assert_eq!(expected, output);
123
    }
124
125
    #[test]
126
    fn two_digits() {
127
        let input = "verify\nthis";
128
        let expected = "   12: verify\n       this";
129
        let mut output = String::new();
130
131
        Indented {
132
            inner: &mut output,
133
            number: Some(12),
134
            started: false,
135
        }
136
        .write_str(input)
137
        .unwrap();
138
139
        assert_eq!(expected, output);
140
    }
141
142
    #[test]
143
    fn no_digits() {
144
        let input = "verify\nthis";
145
        let expected = "    verify\n    this";
146
        let mut output = String::new();
147
148
        Indented {
149
            inner: &mut output,
150
            number: None,
151
            started: false,
152
        }
153
        .write_str(input)
154
        .unwrap();
155
156
        assert_eq!(expected, output);
157
    }
158
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/kind.rs
Line
Count
Source (jump to first uncovered line)
1
// Tagged dispatch mechanism for resolving the behavior of `anyhow!($expr)`.
2
//
3
// When anyhow! is given a single expr argument to turn into anyhow::Error, we
4
// want the resulting Error to pick up the input's implementation of source()
5
// and backtrace() if it has a std::error::Error impl, otherwise require nothing
6
// more than Display and Debug.
7
//
8
// Expressed in terms of specialization, we want something like:
9
//
10
//     trait AnyhowNew {
11
//         fn new(self) -> Error;
12
//     }
13
//
14
//     impl<T> AnyhowNew for T
15
//     where
16
//         T: Display + Debug + Send + Sync + 'static,
17
//     {
18
//         default fn new(self) -> Error {
19
//             /* no std error impl */
20
//         }
21
//     }
22
//
23
//     impl<T> AnyhowNew for T
24
//     where
25
//         T: std::error::Error + Send + Sync + 'static,
26
//     {
27
//         fn new(self) -> Error {
28
//             /* use std error's source() and backtrace() */
29
//         }
30
//     }
31
//
32
// Since specialization is not stable yet, instead we rely on autoref behavior
33
// of method resolution to perform tagged dispatch. Here we have two traits
34
// AdhocKind and TraitKind that both have an anyhow_kind() method. AdhocKind is
35
// implemented whether or not the caller's type has a std error impl, while
36
// TraitKind is implemented only when a std error impl does exist. The ambiguity
37
// is resolved by AdhocKind requiring an extra autoref so that it has lower
38
// precedence.
39
//
40
// The anyhow! macro will set up the call in this form:
41
//
42
//     #[allow(unused_imports)]
43
//     use $crate::__private::{AdhocKind, TraitKind};
44
//     let error = $msg;
45
//     (&error).anyhow_kind().new(error)
46
47
use crate::Error;
48
use core::fmt::{Debug, Display};
49
50
#[cfg(feature = "std")]
51
use crate::StdError;
52
#[cfg(feature = "std")]
53
use alloc::boxed::Box;
54
55
pub struct Adhoc;
56
57
#[doc(hidden)]
58
pub trait AdhocKind: Sized {
59
    #[inline]
60
0
    fn anyhow_kind(&self) -> Adhoc {
61
0
        Adhoc
62
0
    }
63
}
64
65
impl<T> AdhocKind for &T where T: ?Sized + Display + Debug + Send + Sync + 'static {}
66
67
impl Adhoc {
68
    #[cold]
69
0
    pub fn new<M>(self, message: M) -> Error
70
0
    where
71
0
        M: Display + Debug + Send + Sync + 'static,
72
0
    {
73
0
        Error::from_adhoc(message, backtrace!())
74
0
    }
75
}
76
77
pub struct Trait;
78
79
#[doc(hidden)]
80
pub trait TraitKind: Sized {
81
    #[inline]
82
5.01k
    fn anyhow_kind(&self) -> Trait {
83
5.01k
        Trait
84
5.01k
    }
_RNvYNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorNtNtCskkyJyiFoyZJ_6anyhow4kind9TraitKind11anyhow_kindCs5HNiFFfDLPG_6decode
Line
Count
Source
82
5.01k
    fn anyhow_kind(&self) -> Trait {
83
5.01k
        Trait
84
5.01k
    }
Unexecuted instantiation: _RNvYpNtNtCskkyJyiFoyZJ_6anyhow4kind9TraitKind11anyhow_kindB7_
85
}
86
87
impl<E> TraitKind for E where E: Into<Error> {}
88
89
impl Trait {
90
    #[cold]
91
5.01k
    pub fn new<E>(self, error: E) -> Error
92
5.01k
    where
93
5.01k
        E: Into<Error>,
94
5.01k
    {
95
5.01k
        error.into()
96
5.01k
    }
_RINvMs1_NtCskkyJyiFoyZJ_6anyhow4kindNtB6_5Trait3newNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Line
Count
Source
91
5.01k
    pub fn new<E>(self, error: E) -> Error
92
5.01k
    where
93
5.01k
        E: Into<Error>,
94
5.01k
    {
95
5.01k
        error.into()
96
5.01k
    }
Unexecuted instantiation: _RINvMs1_NtCskkyJyiFoyZJ_6anyhow4kindNtB6_5Trait3newpEB8_
97
}
98
99
#[cfg(feature = "std")]
100
pub struct Boxed;
101
102
#[cfg(feature = "std")]
103
#[doc(hidden)]
104
pub trait BoxedKind: Sized {
105
    #[inline]
106
0
    fn anyhow_kind(&self) -> Boxed {
107
0
        Boxed
108
0
    }
109
}
110
111
#[cfg(feature = "std")]
112
impl BoxedKind for Box<dyn StdError + Send + Sync> {}
113
114
#[cfg(feature = "std")]
115
impl Boxed {
116
    #[cold]
117
0
    pub fn new(self, error: Box<dyn StdError + Send + Sync>) -> Error {
118
0
        let backtrace = backtrace_if_absent!(&*error);
119
0
        Error::from_boxed(error, backtrace)
120
0
    }
121
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! [![github]](https://github.com/dtolnay/anyhow)&ensp;[![crates-io]](https://crates.io/crates/anyhow)&ensp;[![docs-rs]](https://docs.rs/anyhow)
2
//!
3
//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
4
//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
5
//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
6
//!
7
//! <br>
8
//!
9
//! This library provides [`anyhow::Error`][Error], a trait object based error
10
//! type for easy idiomatic error handling in Rust applications.
11
//!
12
//! <br>
13
//!
14
//! # Details
15
//!
16
//! - Use `Result<T, anyhow::Error>`, or equivalently `anyhow::Result<T>`, as
17
//!   the return type of any fallible function.
18
//!
19
//!   Within the function, use `?` to easily propagate any error that implements
20
//!   the [`std::error::Error`] trait.
21
//!
22
//!   ```
23
//!   # pub trait Deserialize {}
24
//!   #
25
//!   # mod serde_json {
26
//!   #     use super::Deserialize;
27
//!   #     use std::io;
28
//!   #
29
//!   #     pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
30
//!   #         unimplemented!()
31
//!   #     }
32
//!   # }
33
//!   #
34
//!   # struct ClusterMap;
35
//!   #
36
//!   # impl Deserialize for ClusterMap {}
37
//!   #
38
//!   use anyhow::Result;
39
//!
40
//!   fn get_cluster_info() -> Result<ClusterMap> {
41
//!       let config = std::fs::read_to_string("cluster.json")?;
42
//!       let map: ClusterMap = serde_json::from_str(&config)?;
43
//!       Ok(map)
44
//!   }
45
//!   #
46
//!   # fn main() {}
47
//!   ```
48
//!
49
//! - Attach context to help the person troubleshooting the error understand
50
//!   where things went wrong. A low-level error like "No such file or
51
//!   directory" can be annoying to debug without more context about what higher
52
//!   level step the application was in the middle of.
53
//!
54
//!   ```
55
//!   # struct It;
56
//!   #
57
//!   # impl It {
58
//!   #     fn detach(&self) -> Result<()> {
59
//!   #         unimplemented!()
60
//!   #     }
61
//!   # }
62
//!   #
63
//!   use anyhow::{Context, Result};
64
//!
65
//!   fn main() -> Result<()> {
66
//!       # return Ok(());
67
//!       #
68
//!       # const _: &str = stringify! {
69
//!       ...
70
//!       # };
71
//!       #
72
//!       # let it = It;
73
//!       # let path = "./path/to/instrs.json";
74
//!       #
75
//!       it.detach().context("Failed to detach the important thing")?;
76
//!
77
//!       let content = std::fs::read(path)
78
//!           .with_context(|| format!("Failed to read instrs from {}", path))?;
79
//!       #
80
//!       # const _: &str = stringify! {
81
//!       ...
82
//!       # };
83
//!       #
84
//!       # Ok(())
85
//!   }
86
//!   ```
87
//!
88
//!   ```console
89
//!   Error: Failed to read instrs from ./path/to/instrs.json
90
//!
91
//!   Caused by:
92
//!       No such file or directory (os error 2)
93
//!   ```
94
//!
95
//! - Downcasting is supported and can be by value, by shared reference, or by
96
//!   mutable reference as needed.
97
//!
98
//!   ```
99
//!   # use anyhow::anyhow;
100
//!   # use std::fmt::{self, Display};
101
//!   # use std::task::Poll;
102
//!   #
103
//!   # #[derive(Debug)]
104
//!   # enum DataStoreError {
105
//!   #     Censored(()),
106
//!   # }
107
//!   #
108
//!   # impl Display for DataStoreError {
109
//!   #     fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
110
//!   #         unimplemented!()
111
//!   #     }
112
//!   # }
113
//!   #
114
//!   # impl std::error::Error for DataStoreError {}
115
//!   #
116
//!   # const REDACTED_CONTENT: () = ();
117
//!   #
118
//!   # let error = anyhow!("...");
119
//!   # let root_cause = &error;
120
//!   #
121
//!   # let ret =
122
//!   // If the error was caused by redaction, then return a
123
//!   // tombstone instead of the content.
124
//!   match root_cause.downcast_ref::<DataStoreError>() {
125
//!       Some(DataStoreError::Censored(_)) => Ok(Poll::Ready(REDACTED_CONTENT)),
126
//!       None => Err(error),
127
//!   }
128
//!   # ;
129
//!   ```
130
//!
131
//! - If using Rust &ge; 1.65, a backtrace is captured and printed with the
132
//!   error if the underlying error type does not already provide its own. In
133
//!   order to see backtraces, they must be enabled through the environment
134
//!   variables described in [`std::backtrace`]:
135
//!
136
//!   - If you want panics and errors to both have backtraces, set
137
//!     `RUST_BACKTRACE=1`;
138
//!   - If you want only errors to have backtraces, set `RUST_LIB_BACKTRACE=1`;
139
//!   - If you want only panics to have backtraces, set `RUST_BACKTRACE=1` and
140
//!     `RUST_LIB_BACKTRACE=0`.
141
//!
142
//!   [`std::backtrace`]: https://doc.rust-lang.org/std/backtrace/index.html#environment-variables
143
//!
144
//! - Anyhow works with any error type that has an impl of `std::error::Error`,
145
//!   including ones defined in your crate. We do not bundle a `derive(Error)`
146
//!   macro but you can write the impls yourself or use a standalone macro like
147
//!   [thiserror].
148
//!
149
//!   [thiserror]: https://github.com/dtolnay/thiserror
150
//!
151
//!   ```
152
//!   use thiserror::Error;
153
//!
154
//!   #[derive(Error, Debug)]
155
//!   pub enum FormatError {
156
//!       #[error("Invalid header (expected {expected:?}, got {found:?})")]
157
//!       InvalidHeader {
158
//!           expected: String,
159
//!           found: String,
160
//!       },
161
//!       #[error("Missing attribute: {0}")]
162
//!       MissingAttribute(String),
163
//!   }
164
//!   ```
165
//!
166
//! - One-off error messages can be constructed using the `anyhow!` macro, which
167
//!   supports string interpolation and produces an `anyhow::Error`.
168
//!
169
//!   ```
170
//!   # use anyhow::{anyhow, Result};
171
//!   #
172
//!   # fn demo() -> Result<()> {
173
//!   #     let missing = "...";
174
//!   return Err(anyhow!("Missing attribute: {}", missing));
175
//!   #     Ok(())
176
//!   # }
177
//!   ```
178
//!
179
//!   A `bail!` macro is provided as a shorthand for the same early return.
180
//!
181
//!   ```
182
//!   # use anyhow::{bail, Result};
183
//!   #
184
//!   # fn demo() -> Result<()> {
185
//!   #     let missing = "...";
186
//!   bail!("Missing attribute: {}", missing);
187
//!   #     Ok(())
188
//!   # }
189
//!   ```
190
//!
191
//! <br>
192
//!
193
//! # No-std support
194
//!
195
//! In no_std mode, almost all of the same API is available and works the same
196
//! way. To depend on Anyhow in no_std mode, disable our default enabled "std"
197
//! feature in Cargo.toml. A global allocator is required.
198
//!
199
//! ```toml
200
//! [dependencies]
201
//! anyhow = { version = "1.0", default-features = false }
202
//! ```
203
//!
204
//! Since the `?`-based error conversions would normally rely on the
205
//! `std::error::Error` trait which is only available through std, no_std mode
206
//! will require an explicit `.map_err(Error::msg)` when working with a
207
//! non-Anyhow error type inside a function that returns Anyhow's error type.
208
209
#![doc(html_root_url = "https://docs.rs/anyhow/1.0.85")]
210
#![cfg_attr(error_generic_member_access, feature(error_generic_member_access))]
211
#![cfg_attr(doc_cfg, feature(doc_cfg))]
212
#![no_std]
213
#![deny(dead_code, unused_imports, unused_mut)]
214
#![cfg_attr(
215
    not(anyhow_no_unsafe_op_in_unsafe_fn_lint),
216
    deny(unsafe_op_in_unsafe_fn)
217
)]
218
#![cfg_attr(anyhow_no_unsafe_op_in_unsafe_fn_lint, allow(unused_unsafe))]
219
#![allow(
220
    clippy::doc_markdown,
221
    clippy::enum_glob_use,
222
    clippy::explicit_auto_deref,
223
    clippy::extra_unused_type_parameters,
224
    clippy::incompatible_msrv,
225
    clippy::let_underscore_untyped,
226
    clippy::missing_errors_doc,
227
    clippy::missing_panics_doc,
228
    clippy::module_name_repetitions,
229
    clippy::must_use_candidate,
230
    clippy::needless_doctest_main,
231
    clippy::new_ret_no_self,
232
    clippy::redundant_else,
233
    clippy::return_self_not_must_use,
234
    clippy::struct_field_names,
235
    clippy::unused_self,
236
    clippy::used_underscore_binding,
237
    clippy::wildcard_imports,
238
    clippy::wrong_self_convention
239
)]
240
241
#[cfg(all(
242
    anyhow_nightly_testing,
243
    feature = "std",
244
    not(error_generic_member_access)
245
))]
246
compile_error!("Build script probe failed to compile.");
247
248
extern crate alloc;
249
250
#[cfg(feature = "std")]
251
extern crate std;
252
253
#[macro_use]
254
mod backtrace;
255
mod chain;
256
mod context;
257
mod ensure;
258
mod error;
259
mod fmt;
260
mod kind;
261
mod macros;
262
mod ptr;
263
mod wrapper;
264
265
use crate::error::ErrorImpl;
266
use crate::ptr::Own;
267
use core::fmt::Display;
268
269
#[cfg(not(feature = "std"))]
270
use core::fmt::Debug;
271
272
#[cfg(feature = "std")]
273
use std::error::Error as StdError;
274
275
#[cfg(not(feature = "std"))]
276
trait StdError: Debug + Display {
277
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
278
        None
279
    }
280
}
281
282
#[doc(no_inline)]
283
pub use anyhow as format_err;
284
285
/// The `Error` type, a wrapper around a dynamic error type.
286
///
287
/// `Error` works a lot like `Box<dyn std::error::Error>`, but with these
288
/// differences:
289
///
290
/// - `Error` requires that the error is `Send`, `Sync`, and `'static`.
291
/// - `Error` guarantees that a backtrace is available, even if the underlying
292
///   error type does not provide one.
293
/// - `Error` is represented as a narrow pointer &mdash; exactly one word in
294
///   size instead of two.
295
///
296
/// <br>
297
///
298
/// # Display representations
299
///
300
/// When you print an error object using "{}" or to_string(), only the outermost
301
/// underlying error or context is printed, not any of the lower level causes.
302
/// This is exactly as if you had called the Display impl of the error from
303
/// which you constructed your anyhow::Error.
304
///
305
/// ```console
306
/// Failed to read instrs from ./path/to/instrs.json
307
/// ```
308
///
309
/// To print causes as well using anyhow's default formatting of causes, use the
310
/// alternate selector "{:#}".
311
///
312
/// ```console
313
/// Failed to read instrs from ./path/to/instrs.json: No such file or directory (os error 2)
314
/// ```
315
///
316
/// The Debug format "{:?}" includes your backtrace if one was captured. Note
317
/// that this is the representation you get by default if you return an error
318
/// from `fn main` instead of printing it explicitly yourself.
319
///
320
/// ```console
321
/// Error: Failed to read instrs from ./path/to/instrs.json
322
///
323
/// Caused by:
324
///     No such file or directory (os error 2)
325
/// ```
326
///
327
/// and if there is a backtrace available:
328
///
329
/// ```console
330
/// Error: Failed to read instrs from ./path/to/instrs.json
331
///
332
/// Caused by:
333
///     No such file or directory (os error 2)
334
///
335
/// Stack backtrace:
336
///    0: <E as anyhow::context::ext::StdError>::ext_context
337
///              at /git/anyhow/src/backtrace.rs:26
338
///    1: core::result::Result<T,E>::map_err
339
///              at /git/rustc/src/libcore/result.rs:596
340
///    2: anyhow::context::<impl anyhow::Context<T,E> for core::result::Result<T,E>>::with_context
341
///              at /git/anyhow/src/context.rs:58
342
///    3: testing::main
343
///              at src/main.rs:5
344
///    4: std::rt::lang_start
345
///              at /git/rustc/src/libstd/rt.rs:61
346
///    5: main
347
///    6: __libc_start_main
348
///    7: _start
349
/// ```
350
///
351
/// To see a conventional struct-style Debug representation, use "{:#?}".
352
///
353
/// ```console
354
/// Error {
355
///     context: "Failed to read instrs from ./path/to/instrs.json",
356
///     source: Os {
357
///         code: 2,
358
///         kind: NotFound,
359
///         message: "No such file or directory",
360
///     },
361
/// }
362
/// ```
363
///
364
/// If none of the built-in representations are appropriate and you would prefer
365
/// to render the error and its cause chain yourself, it can be done something
366
/// like this:
367
///
368
/// ```
369
/// use anyhow::{Context, Result};
370
///
371
/// fn main() {
372
///     if let Err(err) = try_main() {
373
///         eprintln!("ERROR: {}", err);
374
///         err.chain().skip(1).for_each(|cause| eprintln!("because: {}", cause));
375
///         std::process::exit(1);
376
///     }
377
/// }
378
///
379
/// fn try_main() -> Result<()> {
380
///     # const IGNORE: &str = stringify! {
381
///     ...
382
///     # };
383
///     # Ok(())
384
/// }
385
/// ```
386
#[repr(transparent)]
387
pub struct Error {
388
    inner: Own<ErrorImpl>,
389
}
390
391
/// Iterator of a chain of source errors.
392
///
393
/// This type is the iterator returned by [`Error::chain`].
394
///
395
/// # Example
396
///
397
/// ```
398
/// use anyhow::Error;
399
/// use std::io;
400
///
401
/// pub fn underlying_io_error_kind(error: &Error) -> Option<io::ErrorKind> {
402
///     for cause in error.chain() {
403
///         if let Some(io_error) = cause.downcast_ref::<io::Error>() {
404
///             return Some(io_error.kind());
405
///         }
406
///     }
407
///     None
408
/// }
409
/// ```
410
#[cfg(feature = "std")]
411
#[cfg_attr(doc_cfg, doc(cfg(feature = "std")))]
412
#[derive(Clone)]
413
pub struct Chain<'a> {
414
    state: crate::chain::ChainState<'a>,
415
}
416
417
/// `Result<T, Error>`
418
///
419
/// This is a reasonable return type to use throughout your application but also
420
/// for `fn main`; if you do, failures will be printed along with any
421
/// [context][Context] and a backtrace if one was captured.
422
///
423
/// `anyhow::Result` may be used with one *or* two type parameters.
424
///
425
/// ```rust
426
/// use anyhow::Result;
427
///
428
/// # const IGNORE: &str = stringify! {
429
/// fn demo1() -> Result<T> {...}
430
///            // ^ equivalent to std::result::Result<T, anyhow::Error>
431
///
432
/// fn demo2() -> Result<T, OtherError> {...}
433
///            // ^ equivalent to std::result::Result<T, OtherError>
434
/// # };
435
/// ```
436
///
437
/// # Example
438
///
439
/// ```
440
/// # pub trait Deserialize {}
441
/// #
442
/// # mod serde_json {
443
/// #     use super::Deserialize;
444
/// #     use std::io;
445
/// #
446
/// #     pub fn from_str<T: Deserialize>(json: &str) -> io::Result<T> {
447
/// #         unimplemented!()
448
/// #     }
449
/// # }
450
/// #
451
/// # #[derive(Debug)]
452
/// # struct ClusterMap;
453
/// #
454
/// # impl Deserialize for ClusterMap {}
455
/// #
456
/// use anyhow::Result;
457
///
458
/// fn main() -> Result<()> {
459
///     # return Ok(());
460
///     let config = std::fs::read_to_string("cluster.json")?;
461
///     let map: ClusterMap = serde_json::from_str(&config)?;
462
///     println!("cluster info: {:#?}", map);
463
///     Ok(())
464
/// }
465
/// ```
466
pub type Result<T, E = Error> = core::result::Result<T, E>;
467
468
/// Provides the `context` method for `Result`.
469
///
470
/// This trait is sealed and cannot be implemented for types outside of
471
/// `anyhow`.
472
///
473
/// <br>
474
///
475
/// # Example
476
///
477
/// ```
478
/// use anyhow::{Context, Result};
479
/// use std::fs;
480
/// use std::path::PathBuf;
481
///
482
/// pub struct ImportantThing {
483
///     path: PathBuf,
484
/// }
485
///
486
/// impl ImportantThing {
487
///     # const IGNORE: &'static str = stringify! {
488
///     pub fn detach(&mut self) -> Result<()> {...}
489
///     # };
490
///     # fn detach(&mut self) -> Result<()> {
491
///     #     unimplemented!()
492
///     # }
493
/// }
494
///
495
/// pub fn do_it(mut it: ImportantThing) -> Result<Vec<u8>> {
496
///     it.detach().context("Failed to detach the important thing")?;
497
///
498
///     let path = &it.path;
499
///     let content = fs::read(path)
500
///         .with_context(|| format!("Failed to read instrs from {}", path.display()))?;
501
///
502
///     Ok(content)
503
/// }
504
/// ```
505
///
506
/// When printed, the outermost context would be printed first and the lower
507
/// level underlying causes would be enumerated below.
508
///
509
/// ```console
510
/// Error: Failed to read instrs from ./path/to/instrs.json
511
///
512
/// Caused by:
513
///     No such file or directory (os error 2)
514
/// ```
515
///
516
/// Refer to the [Display representations] documentation for other forms in
517
/// which this context chain can be rendered.
518
///
519
/// [Display representations]: Error#display-representations
520
///
521
/// <br>
522
///
523
/// # Effect on downcasting
524
///
525
/// After attaching context of type `C` onto an error of type `E`, the resulting
526
/// `anyhow::Error` may be downcast to `C` **or** to `E`.
527
///
528
/// That is, in codebases that rely on downcasting, Anyhow's context supports
529
/// both of the following use cases:
530
///
531
///   - **Attaching context whose type is insignificant onto errors whose type
532
///     is used in downcasts.**
533
///
534
///     In other error libraries whose context is not designed this way, it can
535
///     be risky to introduce context to existing code because new context might
536
///     break existing working downcasts. In Anyhow, any downcast that worked
537
///     before adding context will continue to work after you add a context, so
538
///     you should freely add human-readable context to errors wherever it would
539
///     be helpful.
540
///
541
///     ```
542
///     # use anyhow::bail;
543
///     # use thiserror::Error;
544
///     #
545
///     # #[derive(Error, Debug)]
546
///     # #[error("???")]
547
///     # struct SuspiciousError;
548
///     #
549
///     # fn helper() -> Result<()> {
550
///     #     bail!(SuspiciousError);
551
///     # }
552
///     #
553
///     use anyhow::{Context, Result};
554
///
555
///     fn do_it() -> Result<()> {
556
///         helper().context("Failed to complete the work")?;
557
///         # const IGNORE: &str = stringify! {
558
///         ...
559
///         # };
560
///         # unreachable!()
561
///     }
562
///
563
///     fn main() {
564
///         let err = do_it().unwrap_err();
565
///         if let Some(e) = err.downcast_ref::<SuspiciousError>() {
566
///             // If helper() returned SuspiciousError, this downcast will
567
///             // correctly succeed even with the context in between.
568
///             # return;
569
///         }
570
///         # panic!("expected downcast to succeed");
571
///     }
572
///     ```
573
///
574
///   - **Attaching context whose type is used in downcasts onto errors whose
575
///     type is insignificant.**
576
///
577
///     Some codebases prefer to use machine-readable context to categorize
578
///     lower level errors in a way that will be actionable to higher levels of
579
///     the application.
580
///
581
///     ```
582
///     # use anyhow::bail;
583
///     # use thiserror::Error;
584
///     #
585
///     # #[derive(Error, Debug)]
586
///     # #[error("???")]
587
///     # struct HelperFailed;
588
///     #
589
///     # fn helper() -> Result<()> {
590
///     #     bail!("no such file or directory");
591
///     # }
592
///     #
593
///     use anyhow::{Context, Result};
594
///
595
///     fn do_it() -> Result<()> {
596
///         helper().context(HelperFailed)?;
597
///         # const IGNORE: &str = stringify! {
598
///         ...
599
///         # };
600
///         # unreachable!()
601
///     }
602
///
603
///     fn main() {
604
///         let err = do_it().unwrap_err();
605
///         if let Some(e) = err.downcast_ref::<HelperFailed>() {
606
///             // If helper failed, this downcast will succeed because
607
///             // HelperFailed is the context that has been attached to
608
///             // that error.
609
///             # return;
610
///         }
611
///         # panic!("expected downcast to succeed");
612
///     }
613
///     ```
614
pub trait Context<T, E>: context::private::Sealed {
615
    /// Wrap the error value with additional context.
616
    fn context<C>(self, context: C) -> Result<T, Error>
617
    where
618
        C: Display + Send + Sync + 'static;
619
620
    /// Wrap the error value with additional context that is evaluated lazily
621
    /// only once an error does occur.
622
    fn with_context<C, F>(self, f: F) -> Result<T, Error>
623
    where
624
        C: Display + Send + Sync + 'static,
625
        F: FnOnce() -> C;
626
}
627
628
/// Equivalent to Ok::<_, anyhow::Error>(value).
629
///
630
/// This simplifies creation of an anyhow::Result in places where type inference
631
/// cannot deduce the `E` type of the result &mdash; without needing to write
632
/// `Ok::<_, anyhow::Error>(value)`.
633
///
634
/// One might think that `anyhow::Result::Ok(value)` would work in such cases
635
/// but it does not.
636
///
637
/// ```console
638
/// error[E0282]: type annotations needed for `std::result::Result<i32, E>`
639
///   --> src/main.rs:11:13
640
///    |
641
/// 11 |     let _ = anyhow::Result::Ok(1);
642
///    |         -   ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `E` declared on the enum `Result`
643
///    |         |
644
///    |         consider giving this pattern the explicit type `std::result::Result<i32, E>`, where the type parameter `E` is specified
645
/// ```
646
#[allow(non_snake_case)]
647
0
pub fn Ok<T>(t: T) -> Result<T> {
648
0
    Result::Ok(t)
649
0
}
650
651
// Not public API. Referenced by macro-generated code.
652
#[doc(hidden)]
653
pub mod __private {
654
    use self::not::Bool;
655
    use crate::Error;
656
    use alloc::fmt;
657
    use core::fmt::Arguments;
658
659
    #[doc(hidden)]
660
    pub use crate::ensure::{BothDebug, NotBothDebug};
661
    #[doc(hidden)]
662
    pub use alloc::format;
663
    #[doc(hidden)]
664
    pub use core::result::Result::Err;
665
    #[doc(hidden)]
666
    pub use core::{concat, format_args, stringify};
667
668
    #[doc(hidden)]
669
    pub mod kind {
670
        #[doc(hidden)]
671
        pub use crate::kind::{AdhocKind, TraitKind};
672
673
        #[cfg(feature = "std")]
674
        #[doc(hidden)]
675
        pub use crate::kind::BoxedKind;
676
    }
677
678
    #[doc(hidden)]
679
    #[inline]
680
    #[cold]
681
0
    pub fn format_err(args: Arguments) -> Error {
682
0
        #[cfg(anyhow_no_fmt_arguments_as_str)]
683
0
        let fmt_arguments_as_str = None::<&str>;
684
0
        #[cfg(not(anyhow_no_fmt_arguments_as_str))]
685
0
        let fmt_arguments_as_str = args.as_str();
686
687
0
        if let Some(message) = fmt_arguments_as_str {
688
            // anyhow!("literal"), can downcast to &'static str
689
0
            Error::msg(message)
690
        } else {
691
            // anyhow!("interpolate {var}"), can downcast to String
692
0
            Error::msg(fmt::format(args))
693
        }
694
0
    }
Unexecuted instantiation: _RNvNtCskkyJyiFoyZJ_6anyhow9___private10format_errCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvNtCskkyJyiFoyZJ_6anyhow9___private10format_errB3_
695
696
    #[doc(hidden)]
697
    #[inline]
698
    #[cold]
699
    #[must_use]
700
0
    pub fn must_use(error: Error) -> Error {
701
0
        error
702
0
    }
703
704
    #[doc(hidden)]
705
    #[inline]
706
0
    pub fn not(cond: impl Bool) -> bool {
707
0
        cond.not()
708
0
    }
709
710
    mod not {
711
        #[doc(hidden)]
712
        pub trait Bool {
713
            fn not(self) -> bool;
714
        }
715
716
        impl Bool for bool {
717
            #[inline]
718
0
            fn not(self) -> bool {
719
0
                !self
720
0
            }
721
        }
722
723
        impl Bool for &bool {
724
            #[inline]
725
0
            fn not(self) -> bool {
726
0
                !*self
727
0
            }
728
        }
729
    }
730
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/ptr.rs
Line
Count
Source (jump to first uncovered line)
1
use alloc::boxed::Box;
2
use core::marker::PhantomData;
3
use core::ptr::NonNull;
4
5
#[repr(transparent)]
6
pub struct Own<T>
7
where
8
    T: ?Sized,
9
{
10
    pub ptr: NonNull<T>,
11
}
12
13
unsafe impl<T> Send for Own<T> where T: ?Sized {}
14
15
unsafe impl<T> Sync for Own<T> where T: ?Sized {}
16
17
impl<T> Copy for Own<T> where T: ?Sized {}
18
19
impl<T> Clone for Own<T>
20
where
21
    T: ?Sized,
22
{
23
0
    fn clone(&self) -> Self {
24
0
        *self
25
0
    }
26
}
27
28
impl<T> Own<T>
29
where
30
    T: ?Sized,
31
{
32
5.01k
    pub fn new(ptr: Box<T>) -> Self {
33
5.01k
        Own {
34
5.01k
            ptr: unsafe { NonNull::new_unchecked(Box::into_raw(ptr)) },
35
5.01k
        }
36
5.01k
    }
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtBJ_12ContextErrorReNtB7_5ErrorEEE3newCs5HNiFFfDLPG_6decode
_RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEE3newCs5HNiFFfDLPG_6decode
Line
Count
Source
32
5.01k
    pub fn new(ptr: Box<T>) -> Self {
33
5.01k
        Own {
34
5.01k
            ptr: unsafe { NonNull::new_unchecked(Box::into_raw(ptr)) },
35
5.01k
        }
36
5.01k
    }
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorReEEE3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE3newB7_
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorReEEE3newB7_
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplNtNtB7_7wrapper10BoxedErrorEE3newB7_
37
38
10.0k
    pub fn cast<U: CastTo>(self) -> Own<U::Target> {
39
10.0k
        Own {
40
10.0k
            ptr: self.ptr.cast(),
41
10.0k
        }
42
10.0k
    }
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnINtNtB8_5error9ErrorImplINtBK_12ContextErrorReNtB8_5ErrorEEE4castBI_ECs5HNiFFfDLPG_6decode
_RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnINtNtB8_5error9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEE4castBI_ECs5HNiFFfDLPG_6decode
Line
Count
Source
38
5.01k
    pub fn cast<U: CastTo>(self) -> Own<U::Target> {
39
5.01k
        Own {
40
5.01k
            ptr: self.ptr.cast(),
41
5.01k
        }
42
5.01k
    }
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtBJ_12ContextErrorReNtB8_5ErrorEEECs5HNiFFfDLPG_6decode
_RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_NtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEECs5HNiFFfDLPG_6decode
Line
Count
Source
38
5.01k
    pub fn cast<U: CastTo>(self) -> Own<U::Target> {
39
5.01k
        Own {
40
5.01k
            ptr: self.ptr.cast(),
41
5.01k
        }
42
5.01k
    }
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEEECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtBJ_12ContextErrorReINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropNtB8_5ErrorEEEECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtBJ_12ContextErrorINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropReENtB8_5ErrorEEECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnINtNtB8_5error9ErrorImplINtNtB8_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE4castBI_ECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnINtNtB8_5error9ErrorImplINtNtB8_7wrapper12MessageErrorReEEE4castBI_ECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtB8_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtB8_7wrapper12MessageErrorReEEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropNtNtCsbpSlAbJY2yh_5alloc6string6StringEEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropReEEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnINtNtB8_5error9ErrorImplINtNtB8_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE4castBI_EB8_
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnINtNtB8_5error9ErrorImplINtNtB8_7wrapper12MessageErrorReEEE4castBI_EB8_
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnINtNtB8_5error9ErrorImplNtNtB8_7wrapper10BoxedErrorEE4castBI_EB8_
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtB8_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEEB8_
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtB8_7wrapper12MessageErrorReEEEB8_
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_NtNtB8_7wrapper10BoxedErrorEEB8_
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDNtNtB1l_5error5ErrorNtNtB1l_6marker4SendNtB37_4SyncEL_EEEEB8_
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropNtNtCsbpSlAbJY2yh_5alloc6string6StringEEEB8_
Unexecuted instantiation: _RINvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3OwnNtNtB8_5error9ErrorImplE4castIBH_INtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropReEEEB8_
43
44
5.01k
    pub unsafe fn boxed(self) -> Box<T> {
45
5.01k
        unsafe { Box::from_raw(self.ptr.as_ptr()) }
46
5.01k
    }
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtBJ_12ContextErrorINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropReENtB7_5ErrorEEE5boxedCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtBJ_12ContextErrorReINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropNtB7_5ErrorEEEE5boxedCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtBJ_12ContextErrorReNtB7_5ErrorEEE5boxedCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEEE5boxedCs5HNiFFfDLPG_6decode
_RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEE5boxedCs5HNiFFfDLPG_6decode
Line
Count
Source
44
5.01k
    pub unsafe fn boxed(self) -> Box<T> {
45
5.01k
        unsafe { Box::from_raw(self.ptr.as_ptr()) }
46
5.01k
    }
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE5boxedCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorReEEE5boxedCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE5boxedCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropReEEE5boxedCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE5boxedB7_
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorReEEE5boxedB7_
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDNtNtB1b_5error5ErrorNtNtB1b_6marker4SendNtB2X_4SyncEL_EEEE5boxedB7_
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE5boxedB7_
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplINtNtNtCs1ujR1JRCAmI_4core3mem13manually_drop12ManuallyDropReEEE5boxedB7_
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnINtNtB7_5error9ErrorImplNtNtB7_7wrapper10BoxedErrorEE5boxedB7_
47
48
5.01k
    pub fn by_ref(&self) -> Ref<T> {
49
5.01k
        Ref {
50
5.01k
            ptr: self.ptr,
51
5.01k
            lifetime: PhantomData,
52
5.01k
        }
53
5.01k
    }
_RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnNtNtB7_5error9ErrorImplE6by_refCs5HNiFFfDLPG_6decode
Line
Count
Source
48
5.01k
    pub fn by_ref(&self) -> Ref<T> {
49
5.01k
        Ref {
50
5.01k
            ptr: self.ptr,
51
5.01k
            lifetime: PhantomData,
52
5.01k
        }
53
5.01k
    }
Unexecuted instantiation: _RNvMs2_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3OwnNtNtB7_5error9ErrorImplE6by_refB7_
54
55
0
    pub fn by_mut(&mut self) -> Mut<T> {
56
0
        Mut {
57
0
            ptr: self.ptr,
58
0
            lifetime: PhantomData,
59
0
        }
60
0
    }
61
}
62
63
#[repr(transparent)]
64
pub struct Ref<'a, T>
65
where
66
    T: ?Sized,
67
{
68
    pub ptr: NonNull<T>,
69
    lifetime: PhantomData<&'a T>,
70
}
71
72
impl<'a, T> Copy for Ref<'a, T> where T: ?Sized {}
73
74
impl<'a, T> Clone for Ref<'a, T>
75
where
76
    T: ?Sized,
77
{
78
0
    fn clone(&self) -> Self {
79
0
        *self
80
0
    }
81
}
82
83
impl<'a, T> Ref<'a, T>
84
where
85
    T: ?Sized,
86
{
87
0
    pub fn new(ptr: &'a T) -> Self {
88
0
        Ref {
89
0
            ptr: NonNull::from(ptr),
90
0
            lifetime: PhantomData,
91
0
        }
92
0
    }
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefReE3newCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtBJ_12ContextErrorReNtB7_5ErrorEEE3newCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEE3newCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorReEEE3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE3newB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorReEEE3newB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplNtNtB7_7wrapper10BoxedErrorEE3newB7_
93
94
    #[cfg(not(anyhow_no_ptr_addr_of))]
95
5.01k
    pub fn from_raw(ptr: NonNull<T>) -> Self {
96
5.01k
        Ref {
97
5.01k
            ptr,
98
5.01k
            lifetime: PhantomData,
99
5.01k
        }
100
5.01k
    }
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtBL_6marker4SendNtB1i_4SyncEL_E8from_rawCs5HNiFFfDLPG_6decode
_RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorE8from_rawCs5HNiFFfDLPG_6decode
Line
Count
Source
95
5.01k
    pub fn from_raw(ptr: NonNull<T>) -> Self {
96
5.01k
        Ref {
97
5.01k
            ptr,
98
5.01k
            lifetime: PhantomData,
99
5.01k
        }
100
5.01k
    }
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtBL_6marker4SendNtB1i_4SyncEL_E8from_rawCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefNtNtCsbpSlAbJY2yh_5alloc6string6StringE8from_rawCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefReE8from_rawCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtBL_6marker4SendNtB1i_4SyncEL_E8from_rawB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtB1k_6marker4SendNtB1R_4SyncEL_EE8from_rawB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefNtNtCsbpSlAbJY2yh_5alloc6string6StringE8from_rawB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefReE8from_rawB7_
101
102
15.0k
    pub fn cast<U: CastTo>(self) -> Ref<'a, U::Target> {
103
15.0k
        Ref {
104
15.0k
            ptr: self.ptr.cast(),
105
15.0k
            lifetime: PhantomData,
106
15.0k
        }
107
15.0k
    }
_RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefuE4castNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorECs5HNiFFfDLPG_6decode
Line
Count
Source
102
5.01k
    pub fn cast<U: CastTo>(self) -> Ref<'a, U::Target> {
103
5.01k
        Ref {
104
5.01k
            ptr: self.ptr.cast(),
105
5.01k
            lifetime: PhantomData,
106
5.01k
        }
107
5.01k
    }
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_INtBJ_12ContextErrorReNtB8_5ErrorEEECs5HNiFFfDLPG_6decode
_RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_NtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEECs5HNiFFfDLPG_6decode
Line
Count
Source
102
5.01k
    pub fn cast<U: CastTo>(self) -> Ref<'a, U::Target> {
103
5.01k
        Ref {
104
5.01k
            ptr: self.ptr.cast(),
105
5.01k
            lifetime: PhantomData,
106
5.01k
        }
107
5.01k
    }
_RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorE4castuECs5HNiFFfDLPG_6decode
Line
Count
Source
102
5.01k
    pub fn cast<U: CastTo>(self) -> Ref<'a, U::Target> {
103
5.01k
        Ref {
104
5.01k
            ptr: self.ptr.cast(),
105
5.01k
            lifetime: PhantomData,
106
5.01k
        }
107
5.01k
    }
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefReE4castuECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefINtNtB8_5error9ErrorImplINtBK_12ContextErrorReNtB8_5ErrorEEE4castBI_ECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefINtNtB8_5error9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEE4castBI_ECs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_INtNtB8_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_INtNtB8_7wrapper12MessageErrorReEEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_NtNtCsbpSlAbJY2yh_5alloc6string6StringEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtCsbpSlAbJY2yh_5alloc6string6StringE4castuECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_ReEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefReE4castuECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefINtNtB8_5error9ErrorImplINtNtB8_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE4castBI_ECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefINtNtB8_5error9ErrorImplINtNtB8_7wrapper12MessageErrorReEEE4castBI_ECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_INtNtB8_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_INtNtB8_7wrapper12MessageErrorReEEEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_NtNtB8_7wrapper10BoxedErrorEEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_INtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtB1S_6marker4SendNtB2p_4SyncEL_EEEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtB1l_6marker4SendNtB1S_4SyncEL_EE4castuEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_NtNtCsbpSlAbJY2yh_5alloc6string6StringEEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtCsbpSlAbJY2yh_5alloc6string6StringE4castuEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefNtNtB8_5error9ErrorImplE4castIBH_ReEEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefReE4castuEB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefINtNtB8_5error9ErrorImplINtNtB8_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE4castBI_EB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefINtNtB8_5error9ErrorImplINtNtB8_7wrapper12MessageErrorReEEE4castBI_EB8_
Unexecuted instantiation: _RINvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB6_3RefINtNtB8_5error9ErrorImplNtNtB8_7wrapper10BoxedErrorEE4castBI_EB8_
108
109
    #[cfg(not(anyhow_no_ptr_addr_of))]
110
0
    pub fn by_mut(self) -> Mut<'a, T> {
111
0
        Mut {
112
0
            ptr: self.ptr,
113
0
            lifetime: PhantomData,
114
0
        }
115
0
    }
116
117
    #[cfg(not(anyhow_no_ptr_addr_of))]
118
5.01k
    pub fn as_ptr(self) -> *const T {
119
5.01k
        self.ptr.as_ptr() as *const T
120
5.01k
    }
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtBJ_12ContextErrorReNtB7_5ErrorEEE6as_ptrCs5HNiFFfDLPG_6decode
_RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorEE6as_ptrCs5HNiFFfDLPG_6decode
Line
Count
Source
118
5.01k
    pub fn as_ptr(self) -> *const T {
119
5.01k
        self.ptr.as_ptr() as *const T
120
5.01k
    }
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE6as_ptrCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorReEEE6as_ptrCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplNtNtCsbpSlAbJY2yh_5alloc6string6StringEE6as_ptrCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplReEE6as_ptrCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringEEE6as_ptrB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtB7_7wrapper12MessageErrorReEEE6as_ptrB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplNtNtB7_7wrapper10BoxedErrorEE6as_ptrB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtB1I_6marker4SendNtB2f_4SyncEL_EEE6as_ptrB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplNtNtCsbpSlAbJY2yh_5alloc6string6StringEE6as_ptrB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplReEE6as_ptrB7_
121
122
5.01k
    pub unsafe fn deref(self) -> &'a T {
123
5.01k
        unsafe { &*self.ptr.as_ptr() }
124
5.01k
    }
_RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6result11DecodeErrorE5derefCs5HNiFFfDLPG_6decode
Line
Count
Source
122
5.01k
    pub unsafe fn deref(self) -> &'a T {
123
5.01k
        unsafe { &*self.ptr.as_ptr() }
124
5.01k
    }
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefINtNtB7_5error9ErrorImplINtBJ_12ContextErrorReNtB7_5ErrorEEE5derefCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefDNtNtCs1ujR1JRCAmI_4core5error5ErrorNtNtBL_6marker4SendNtB1i_4SyncEL_E5derefB7_
Unexecuted instantiation: _RNvMs5_NtCskkyJyiFoyZJ_6anyhow3ptrINtB5_3RefNtNtB7_5error9ErrorImplE5derefB7_
125
}
126
127
#[repr(transparent)]
128
pub struct Mut<'a, T>
129
where
130
    T: ?Sized,
131
{
132
    pub ptr: NonNull<T>,
133
    lifetime: PhantomData<&'a mut T>,
134
}
135
136
impl<'a, T> Copy for Mut<'a, T> where T: ?Sized {}
137
138
impl<'a, T> Clone for Mut<'a, T>
139
where
140
    T: ?Sized,
141
{
142
0
    fn clone(&self) -> Self {
143
0
        *self
144
0
    }
145
}
146
147
impl<'a, T> Mut<'a, T>
148
where
149
    T: ?Sized,
150
{
151
    #[cfg(anyhow_no_ptr_addr_of)]
152
    pub fn new(ptr: &'a mut T) -> Self {
153
        Mut {
154
            ptr: NonNull::from(ptr),
155
            lifetime: PhantomData,
156
        }
157
    }
158
159
0
    pub fn cast<U: CastTo>(self) -> Mut<'a, U::Target> {
160
0
        Mut {
161
0
            ptr: self.ptr.cast(),
162
0
            lifetime: PhantomData,
163
0
        }
164
0
    }
165
166
    #[cfg(not(anyhow_no_ptr_addr_of))]
167
0
    pub fn by_ref(self) -> Ref<'a, T> {
168
0
        Ref {
169
0
            ptr: self.ptr,
170
0
            lifetime: PhantomData,
171
0
        }
172
0
    }
173
174
0
    pub fn extend<'b>(self) -> Mut<'b, T> {
175
0
        Mut {
176
0
            ptr: self.ptr,
177
0
            lifetime: PhantomData,
178
0
        }
179
0
    }
180
181
0
    pub unsafe fn deref_mut(self) -> &'a mut T {
182
0
        unsafe { &mut *self.ptr.as_ptr() }
183
0
    }
184
}
185
186
impl<'a, T> Mut<'a, T> {
187
0
    pub unsafe fn read(self) -> T {
188
0
        unsafe { self.ptr.as_ptr().read() }
189
0
    }
190
}
191
192
// Force turbofish on all calls of `.cast::<U>()`.
193
pub trait CastTo {
194
    type Target;
195
}
196
197
impl<T> CastTo for T {
198
    type Target = T;
199
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/anyhow-1.0.86/src/wrapper.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::StdError;
2
use core::fmt::{self, Debug, Display};
3
4
#[cfg(feature = "std")]
5
use alloc::boxed::Box;
6
7
#[cfg(error_generic_member_access)]
8
use std::error::Request;
9
10
#[repr(transparent)]
11
pub struct MessageError<M>(pub M);
12
13
impl<M> Debug for MessageError<M>
14
where
15
    M: Display + Debug,
16
{
17
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
18
0
        Debug::fmt(&self.0, f)
19
0
    }
Unexecuted instantiation: _RNvXNtCskkyJyiFoyZJ_6anyhow7wrapperINtB2_12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXNtCskkyJyiFoyZJ_6anyhow7wrapperINtB2_12MessageErrorReENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXNtCskkyJyiFoyZJ_6anyhow7wrapperINtB2_12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtB4_
Unexecuted instantiation: _RNvXNtCskkyJyiFoyZJ_6anyhow7wrapperINtB2_12MessageErrorReENtNtCs1ujR1JRCAmI_4core3fmt5Debug3fmtB4_
20
}
21
22
impl<M> Display for MessageError<M>
23
where
24
    M: Display + Debug,
25
{
26
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27
0
        Display::fmt(&self.0, f)
28
0
    }
Unexecuted instantiation: _RNvXs_NtCskkyJyiFoyZJ_6anyhow7wrapperINtB4_12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs_NtCskkyJyiFoyZJ_6anyhow7wrapperINtB4_12MessageErrorReENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs_NtCskkyJyiFoyZJ_6anyhow7wrapperINtB4_12MessageErrorNtNtCsbpSlAbJY2yh_5alloc6string6StringENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtB6_
Unexecuted instantiation: _RNvXs_NtCskkyJyiFoyZJ_6anyhow7wrapperINtB4_12MessageErrorReENtNtCs1ujR1JRCAmI_4core3fmt7Display3fmtB6_
29
}
30
31
impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}
32
33
#[repr(transparent)]
34
pub struct DisplayError<M>(pub M);
35
36
impl<M> Debug for DisplayError<M>
37
where
38
    M: Display,
39
{
40
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
41
0
        Display::fmt(&self.0, f)
42
0
    }
43
}
44
45
impl<M> Display for DisplayError<M>
46
where
47
    M: Display,
48
{
49
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
50
0
        Display::fmt(&self.0, f)
51
0
    }
52
}
53
54
impl<M> StdError for DisplayError<M> where M: Display + 'static {}
55
56
#[cfg(feature = "std")]
57
#[repr(transparent)]
58
pub struct BoxedError(pub Box<dyn StdError + Send + Sync>);
59
60
#[cfg(feature = "std")]
61
impl Debug for BoxedError {
62
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63
0
        Debug::fmt(&self.0, f)
64
0
    }
65
}
66
67
#[cfg(feature = "std")]
68
impl Display for BoxedError {
69
0
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
70
0
        Display::fmt(&self.0, f)
71
0
    }
72
}
73
74
#[cfg(feature = "std")]
75
impl StdError for BoxedError {
76
0
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
77
0
        self.0.source()
78
0
    }
79
80
    #[cfg(error_generic_member_access)]
81
0
    fn provide<'a>(&'a self, request: &mut Request<'a>) {
82
0
        self.0.provide(request);
83
0
    }
84
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.3.2/src/error.rs
Line
Count
Source (jump to first uncovered line)
1
use std::{error, fmt};
2
3
/// An enumeration of buffer creation errors
4
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5
#[non_exhaustive]
6
pub enum Error {
7
    /// No choices were provided to the Unstructured::choose call
8
    EmptyChoose,
9
    /// There was not enough underlying data to fulfill some request for raw
10
    /// bytes.
11
    NotEnoughData,
12
    /// The input bytes were not of the right format
13
    IncorrectFormat,
14
}
15
16
impl fmt::Display for Error {
17
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
18
0
        match self {
19
0
            Error::EmptyChoose => write!(
20
0
                f,
21
0
                "`arbitrary::Unstructured::choose` must be given a non-empty set of choices"
22
0
            ),
23
0
            Error::NotEnoughData => write!(
24
0
                f,
25
0
                "There is not enough underlying raw data to construct an `Arbitrary` instance"
26
0
            ),
27
0
            Error::IncorrectFormat => write!(
28
0
                f,
29
0
                "The raw data is not of the correct format to construct this type"
30
0
            ),
31
        }
32
0
    }
33
}
34
35
impl error::Error for Error {}
36
37
/// A `Result` with the error type fixed as `arbitrary::Error`.
38
///
39
/// Either an `Ok(T)` or `Err(arbitrary::Error)`.
40
pub type Result<T, E = Error> = std::result::Result<T, E>;
41
42
#[cfg(test)]
43
mod tests {
44
    // Often people will import our custom `Result` type because 99.9% of
45
    // results in a file will be `arbitrary::Result` but then have that one last
46
    // 0.1% that want to have a custom error type. Don't make them prefix that
47
    // 0.1% as `std::result::Result`; instead, let `arbitrary::Result` have an
48
    // overridable error type.
49
    #[test]
50
    fn can_use_custom_error_types_with_result() -> super::Result<(), String> {
51
        Ok(())
52
    }
53
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.3.2/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright © 2019 The Rust Fuzz Project Developers.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! The `Arbitrary` trait crate.
10
//!
11
//! This trait provides an [`Arbitrary`](./trait.Arbitrary.html) trait to
12
//! produce well-typed, structured values, from raw, byte buffers. It is
13
//! generally intended to be used with fuzzers like AFL or libFuzzer. See the
14
//! [`Arbitrary`](./trait.Arbitrary.html) trait's documentation for details on
15
//! automatically deriving, implementing, and/or using the trait.
16
17
#![deny(bad_style)]
18
#![deny(missing_docs)]
19
#![deny(future_incompatible)]
20
#![deny(nonstandard_style)]
21
#![deny(rust_2018_compatibility)]
22
#![deny(rust_2018_idioms)]
23
#![deny(unused)]
24
25
#[cfg(feature = "derive_arbitrary")]
26
pub use derive_arbitrary::*;
27
28
mod error;
29
pub use error::*;
30
31
pub mod unstructured;
32
#[doc(inline)]
33
pub use unstructured::Unstructured;
34
35
pub mod size_hint;
36
37
use core::array;
38
use core::cell::{Cell, RefCell, UnsafeCell};
39
use core::iter;
40
use core::mem;
41
use core::num::{NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize};
42
use core::num::{NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
43
use core::ops::{Range, RangeBounds, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
44
use core::str;
45
use core::time::Duration;
46
use std::borrow::{Cow, ToOwned};
47
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, LinkedList, VecDeque};
48
use std::ffi::{CString, OsString};
49
use std::hash::BuildHasher;
50
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
51
use std::ops::Bound;
52
use std::path::PathBuf;
53
use std::rc::Rc;
54
use std::sync::atomic::{AtomicBool, AtomicIsize, AtomicUsize};
55
use std::sync::{Arc, Mutex};
56
57
/// Generate arbitrary structured values from raw, unstructured data.
58
///
59
/// The `Arbitrary` trait allows you to generate valid structured values, like
60
/// `HashMap`s, or ASTs, or `MyTomlConfig`, or any other data structure from
61
/// raw, unstructured bytes provided by a fuzzer.
62
///
63
/// # Deriving `Arbitrary`
64
///
65
/// Automatically deriving the `Arbitrary` trait is the recommended way to
66
/// implement `Arbitrary` for your types.
67
///
68
/// Using the custom derive requires that you enable the `"derive"` cargo
69
/// feature in your `Cargo.toml`:
70
///
71
/// ```toml
72
/// [dependencies]
73
/// arbitrary = { version = "1", features = ["derive"] }
74
/// ```
75
///
76
/// Then, you add the `#[derive(Arbitrary)]` annotation to your `struct` or
77
/// `enum` type definition:
78
///
79
/// ```
80
/// # #[cfg(feature = "derive")] mod foo {
81
/// use arbitrary::Arbitrary;
82
/// use std::collections::HashSet;
83
///
84
/// #[derive(Arbitrary)]
85
/// pub struct AddressBook {
86
///     friends: HashSet<Friend>,
87
/// }
88
///
89
/// #[derive(Arbitrary, Hash, Eq, PartialEq)]
90
/// pub enum Friend {
91
///     Buddy { name: String },
92
///     Pal { age: usize },
93
/// }
94
/// # }
95
/// ```
96
///
97
/// Every member of the `struct` or `enum` must also implement `Arbitrary`.
98
///
99
/// # Implementing `Arbitrary` By Hand
100
///
101
/// Implementing `Arbitrary` mostly involves nested calls to other `Arbitrary`
102
/// arbitrary implementations for each of your `struct` or `enum`'s members. But
103
/// sometimes you need some amount of raw data, or you need to generate a
104
/// variably-sized collection type, or something of that sort. The
105
/// [`Unstructured`][crate::Unstructured] type helps you with these tasks.
106
///
107
/// ```
108
/// # #[cfg(feature = "derive")] mod foo {
109
/// # pub struct MyCollection<T> { _t: std::marker::PhantomData<T> }
110
/// # impl<T> MyCollection<T> {
111
/// #     pub fn new() -> Self { MyCollection { _t: std::marker::PhantomData } }
112
/// #     pub fn insert(&mut self, element: T) {}
113
/// # }
114
/// use arbitrary::{Arbitrary, Result, Unstructured};
115
///
116
/// impl<'a, T> Arbitrary<'a> for MyCollection<T>
117
/// where
118
///     T: Arbitrary<'a>,
119
/// {
120
///     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
121
///         // Get an iterator of arbitrary `T`s.
122
///         let iter = u.arbitrary_iter::<T>()?;
123
///
124
///         // And then create a collection!
125
///         let mut my_collection = MyCollection::new();
126
///         for elem_result in iter {
127
///             let elem = elem_result?;
128
///             my_collection.insert(elem);
129
///         }
130
///
131
///         Ok(my_collection)
132
///     }
133
/// }
134
/// # }
135
/// ```
136
pub trait Arbitrary<'a>: Sized {
137
    /// Generate an arbitrary value of `Self` from the given unstructured data.
138
    ///
139
    /// Calling `Arbitrary::arbitrary` requires that you have some raw data,
140
    /// perhaps given to you by a fuzzer like AFL or libFuzzer. You wrap this
141
    /// raw data in an `Unstructured`, and then you can call `<MyType as
142
    /// Arbitrary>::arbitrary` to construct an arbitrary instance of `MyType`
143
    /// from that unstructured data.
144
    ///
145
    /// Implementations may return an error if there is not enough data to
146
    /// construct a full instance of `Self`, or they may fill out the rest of
147
    /// `Self` with dummy values. Using dummy values when the underlying data is
148
    /// exhausted can help avoid accidentally "defeating" some of the fuzzer's
149
    /// mutations to the underlying byte stream that might otherwise lead to
150
    /// interesting runtime behavior or new code coverage if only we had just a
151
    /// few more bytes. However, it also requires that implementations for
152
    /// recursive types (e.g. `struct Foo(Option<Box<Foo>>)`) avoid infinite
153
    /// recursion when the underlying data is exhausted.
154
    ///
155
    /// ```
156
    /// # #[cfg(feature = "derive")] fn foo() {
157
    /// use arbitrary::{Arbitrary, Unstructured};
158
    ///
159
    /// #[derive(Arbitrary)]
160
    /// pub struct MyType {
161
    ///     // ...
162
    /// }
163
    ///
164
    /// // Get the raw data from the fuzzer or wherever else.
165
    /// # let get_raw_data_from_fuzzer = || &[];
166
    /// let raw_data: &[u8] = get_raw_data_from_fuzzer();
167
    ///
168
    /// // Wrap that raw data in an `Unstructured`.
169
    /// let mut unstructured = Unstructured::new(raw_data);
170
    ///
171
    /// // Generate an arbitrary instance of `MyType` and do stuff with it.
172
    /// if let Ok(value) = MyType::arbitrary(&mut unstructured) {
173
    /// #   let do_stuff = |_| {};
174
    ///     do_stuff(value);
175
    /// }
176
    /// # }
177
    /// ```
178
    ///
179
    /// See also the documentation for [`Unstructured`][crate::Unstructured].
180
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self>;
181
182
    /// Generate an arbitrary value of `Self` from the entirety of the given
183
    /// unstructured data.
184
    ///
185
    /// This is similar to Arbitrary::arbitrary, however it assumes that it is
186
    /// the last consumer of the given data, and is thus able to consume it all
187
    /// if it needs.  See also the documentation for
188
    /// [`Unstructured`][crate::Unstructured].
189
5.67k
    fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
190
5.67k
        Self::arbitrary(&mut u)
191
5.67k
    }
_RNvYNtNtCs4eJdYXiOSk9_10wasm_smith4core6ModuleNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restCs5HNiFFfDLPG_6decode
Line
Count
Source
189
5.67k
    fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
190
5.67k
        Self::arbitrary(&mut u)
191
5.67k
    }
Unexecuted instantiation: _RNvYNtNtCs4eJdYXiOSk9_10wasm_smith4core6ModuleNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB6_
Unexecuted instantiation: _RNvYNtNtCs4eJdYXiOSk9_10wasm_smith6config6ConfigNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB6_
Unexecuted instantiation: _RNvYNtNtCs4eJdYXiOSk9_10wasm_smith9component13CustomSectionNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB6_
Unexecuted instantiation: _RNvYNtNtCs4eJdYXiOSk9_10wasm_smith9component9ComponentNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB6_
Unexecuted instantiation: _RNvYINtNtCsbpSlAbJY2yh_5alloc2rc2RceENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBB_
Unexecuted instantiation: _RNvYINtNtCsbpSlAbJY2yh_5alloc4sync3ArceENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBE_
Unexecuted instantiation: _RNvYINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxeENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBF_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroaENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerohENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroiENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerojENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerolENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeromENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeronENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerooENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerosENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerotENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroxENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroyENtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBQ_
Unexecuted instantiation: _RNvYNtNtCs1ujR1JRCAmI_4core4time8DurationNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBF_
Unexecuted instantiation: _RNvYNtNtCs5s0IcynIBo_3std4path7PathBufNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBC_
Unexecuted instantiation: _RNvYNtNtNtCs1ujR1JRCAmI_4core3net7ip_addr6IpAddrNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBM_
Unexecuted instantiation: _RNvYNtNtNtCs1ujR1JRCAmI_4core3net7ip_addr8Ipv4AddrNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBO_
Unexecuted instantiation: _RNvYNtNtNtCs1ujR1JRCAmI_4core3net7ip_addr8Ipv6AddrNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBO_
Unexecuted instantiation: _RNvYNtNtNtCs1ujR1JRCAmI_4core4sync6atomic10AtomicBoolNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBR_
Unexecuted instantiation: _RNvYNtNtNtCs1ujR1JRCAmI_4core4sync6atomic11AtomicIsizeNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBS_
Unexecuted instantiation: _RNvYNtNtNtCs1ujR1JRCAmI_4core4sync6atomic11AtomicUsizeNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBS_
Unexecuted instantiation: _RNvYNtNtNtCs5s0IcynIBo_3std3ffi6os_str8OsStringNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBL_
Unexecuted instantiation: _RNvYNtNtNtCsbpSlAbJY2yh_5alloc3ffi5c_str7CStringNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restBM_
Unexecuted instantiation: _RNvYaNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYbNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYcNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYdNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYfNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYhNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYiNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYjNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYlNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYmNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYnNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYoNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYsNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYtNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYuNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYxNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvYyNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_restB5_
192
193
    /// Get a size hint for how many bytes out of an `Unstructured` this type
194
    /// needs to construct itself.
195
    ///
196
    /// This is useful for determining how many elements we should insert when
197
    /// creating an arbitrary collection.
198
    ///
199
    /// The return value is similar to
200
    /// [`Iterator::size_hint`][iterator-size-hint]: it returns a tuple where
201
    /// the first element is a lower bound on the number of bytes required, and
202
    /// the second element is an optional upper bound.
203
    ///
204
    /// The default implementation return `(0, None)` which is correct for any
205
    /// type, but not ultimately that useful. Using `#[derive(Arbitrary)]` will
206
    /// create a better implementation. If you are writing an `Arbitrary`
207
    /// implementation by hand, and your type can be part of a dynamically sized
208
    /// collection (such as `Vec`), you are strongly encouraged to override this
209
    /// default with a better implementation. The
210
    /// [`size_hint`][crate::size_hint] module will help with this task.
211
    ///
212
    /// ## Invariant
213
    ///
214
    /// It must be possible to construct every possible output using only inputs
215
    /// of lengths bounded by these parameters. This applies to both
216
    /// [`Arbitrary::arbitrary`] and [`Arbitrary::arbitrary_take_rest`].
217
    ///
218
    /// This is trivially true for `(0, None)`. To restrict this further, it
219
    /// must be proven that all inputs that are now excluded produced redundant
220
    /// outputs which are still possible to produce using the reduced input
221
    /// space.
222
    ///
223
    /// ## The `depth` Parameter
224
    ///
225
    /// If you 100% know that the type you are implementing `Arbitrary` for is
226
    /// not a recursive type, or your implementation is not transitively calling
227
    /// any other `size_hint` methods, you can ignore the `depth` parameter.
228
    /// Note that if you are implementing `Arbitrary` for a generic type, you
229
    /// cannot guarantee the lack of type recursion!
230
    ///
231
    /// Otherwise, you need to use
232
    /// [`arbitrary::size_hint::recursion_guard(depth)`][crate::size_hint::recursion_guard]
233
    /// to prevent potential infinite recursion when calculating size hints for
234
    /// potentially recursive types:
235
    ///
236
    /// ```
237
    /// use arbitrary::{Arbitrary, Unstructured, size_hint};
238
    ///
239
    /// // This can potentially be a recursive type if `L` or `R` contain
240
    /// // something like `Box<Option<MyEither<L, R>>>`!
241
    /// enum MyEither<L, R> {
242
    ///     Left(L),
243
    ///     Right(R),
244
    /// }
245
    ///
246
    /// impl<'a, L, R> Arbitrary<'a> for MyEither<L, R>
247
    /// where
248
    ///     L: Arbitrary<'a>,
249
    ///     R: Arbitrary<'a>,
250
    /// {
251
    ///     fn arbitrary(u: &mut Unstructured) -> arbitrary::Result<Self> {
252
    ///         // ...
253
    /// #       unimplemented!()
254
    ///     }
255
    ///
256
    ///     fn size_hint(depth: usize) -> (usize, Option<usize>) {
257
    ///         // Protect against potential infinite recursion with
258
    ///         // `recursion_guard`.
259
    ///         size_hint::recursion_guard(depth, |depth| {
260
    ///             // If we aren't too deep, then `recursion_guard` calls
261
    ///             // this closure, which implements the natural size hint.
262
    ///             // Don't forget to use the new `depth` in all nested
263
    ///             // `size_hint` calls! We recommend shadowing the
264
    ///             // parameter, like what is done here, so that you can't
265
    ///             // accidentally use the wrong depth.
266
    ///             size_hint::or(
267
    ///                 <L as Arbitrary>::size_hint(depth),
268
    ///                 <R as Arbitrary>::size_hint(depth),
269
    ///             )
270
    ///         })
271
    ///     }
272
    /// }
273
    /// ```
274
    ///
275
    /// [iterator-size-hint]: https://doc.rust-lang.org/stable/std/iter/trait.Iterator.html#method.size_hint
276
    #[inline]
277
5.67k
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
278
5.67k
        let _ = depth;
279
5.67k
        (0, None)
280
5.67k
    }
_RNvYNtNtCs4eJdYXiOSk9_10wasm_smith4core6ModuleNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9size_hintCs5HNiFFfDLPG_6decode
Line
Count
Source
277
5.67k
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
278
5.67k
        let _ = depth;
279
5.67k
        (0, None)
280
5.67k
    }
Unexecuted instantiation: _RNvYNtNtCs4eJdYXiOSk9_10wasm_smith4core6ModuleNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvYNtNtCs4eJdYXiOSk9_10wasm_smith6config6ConfigNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvYNtNtCs4eJdYXiOSk9_10wasm_smith9component13CustomSectionNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvYNtNtCs4eJdYXiOSk9_10wasm_smith9component9ComponentNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvYpNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9size_hintB5_
281
}
282
283
impl<'a> Arbitrary<'a> for () {
284
0
    fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
285
0
        Ok(())
286
0
    }
287
288
    #[inline]
289
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
290
0
        (0, Some(0))
291
0
    }
292
}
293
294
impl<'a> Arbitrary<'a> for bool {
295
149k
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
296
149k
        Ok(<u8 as Arbitrary<'a>>::arbitrary(u)? & 1 == 1)
297
149k
    }
298
299
    #[inline]
300
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
301
0
        <u8 as Arbitrary<'a>>::size_hint(depth)
302
0
    }
303
}
304
305
macro_rules! impl_arbitrary_for_integers {
306
    ( $( $ty:ty: $unsigned:ty; )* ) => {
307
        $(
308
            impl<'a> Arbitrary<'a> for $ty {
309
277k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
310
277k
                    let mut buf = [0; mem::size_of::<$ty>()];
311
277k
                    u.fill_buffer(&mut buf)?;
312
277k
                    let mut x: $unsigned = 0;
313
373k
                    for i in 0..mem::size_of::<$ty>() {
314
373k
                        x |= buf[i] as $unsigned << (i * 8);
315
373k
                    }
316
277k
                    Ok(x as $ty)
317
277k
                }
_RNvXsI_Csgsv2Y6Qu5CW_9arbitraryhNtB5_9Arbitrary9arbitrary
Line
Count
Source
309
249k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
310
249k
                    let mut buf = [0; mem::size_of::<$ty>()];
311
249k
                    u.fill_buffer(&mut buf)?;
312
249k
                    let mut x: $unsigned = 0;
313
249k
                    for i in 0..mem::size_of::<$ty>() {
314
249k
                        x |= buf[i] as $unsigned << (i * 8);
315
249k
                    }
316
249k
                    Ok(x as $ty)
317
249k
                }
Unexecuted instantiation: _RNvXsJ_Csgsv2Y6Qu5CW_9arbitrarytNtB5_9Arbitrary9arbitrary
_RNvXsK_Csgsv2Y6Qu5CW_9arbitrarymNtB5_9Arbitrary9arbitrary
Line
Count
Source
309
22.5k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
310
22.5k
                    let mut buf = [0; mem::size_of::<$ty>()];
311
22.5k
                    u.fill_buffer(&mut buf)?;
312
22.5k
                    let mut x: $unsigned = 0;
313
90.1k
                    for i in 0..mem::size_of::<$ty>() {
314
90.1k
                        x |= buf[i] as $unsigned << (i * 8);
315
90.1k
                    }
316
22.5k
                    Ok(x as $ty)
317
22.5k
                }
_RNvXsL_Csgsv2Y6Qu5CW_9arbitraryyNtB5_9Arbitrary9arbitrary
Line
Count
Source
309
1.06k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
310
1.06k
                    let mut buf = [0; mem::size_of::<$ty>()];
311
1.06k
                    u.fill_buffer(&mut buf)?;
312
1.06k
                    let mut x: $unsigned = 0;
313
8.51k
                    for i in 0..mem::size_of::<$ty>() {
314
8.51k
                        x |= buf[i] as $unsigned << (i * 8);
315
8.51k
                    }
316
1.06k
                    Ok(x as $ty)
317
1.06k
                }
Unexecuted instantiation: _RNvXsM_Csgsv2Y6Qu5CW_9arbitraryoNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsN_Csgsv2Y6Qu5CW_9arbitraryjNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsO_Csgsv2Y6Qu5CW_9arbitraryaNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsP_Csgsv2Y6Qu5CW_9arbitrarysNtB5_9Arbitrary9arbitrary
_RNvXsQ_Csgsv2Y6Qu5CW_9arbitrarylNtB5_9Arbitrary9arbitrary
Line
Count
Source
309
3.45k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
310
3.45k
                    let mut buf = [0; mem::size_of::<$ty>()];
311
3.45k
                    u.fill_buffer(&mut buf)?;
312
3.45k
                    let mut x: $unsigned = 0;
313
13.8k
                    for i in 0..mem::size_of::<$ty>() {
314
13.8k
                        x |= buf[i] as $unsigned << (i * 8);
315
13.8k
                    }
316
3.45k
                    Ok(x as $ty)
317
3.45k
                }
_RNvXsR_Csgsv2Y6Qu5CW_9arbitraryxNtB5_9Arbitrary9arbitrary
Line
Count
Source
309
1.43k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
310
1.43k
                    let mut buf = [0; mem::size_of::<$ty>()];
311
1.43k
                    u.fill_buffer(&mut buf)?;
312
1.43k
                    let mut x: $unsigned = 0;
313
11.4k
                    for i in 0..mem::size_of::<$ty>() {
314
11.4k
                        x |= buf[i] as $unsigned << (i * 8);
315
11.4k
                    }
316
1.43k
                    Ok(x as $ty)
317
1.43k
                }
Unexecuted instantiation: _RNvXsS_Csgsv2Y6Qu5CW_9arbitrarynNtB5_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXsT_Csgsv2Y6Qu5CW_9arbitraryiNtB5_9Arbitrary9arbitrary
318
319
                #[inline]
320
14.1k
                fn size_hint(_depth: usize) -> (usize, Option<usize>) {
321
14.1k
                    let n = mem::size_of::<$ty>();
322
14.1k
                    (n, Some(n))
323
14.1k
                }
_RNvXsI_Csgsv2Y6Qu5CW_9arbitraryhNtB5_9Arbitrary9size_hintCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
320
14.1k
                fn size_hint(_depth: usize) -> (usize, Option<usize>) {
321
14.1k
                    let n = mem::size_of::<$ty>();
322
14.1k
                    (n, Some(n))
323
14.1k
                }
Unexecuted instantiation: _RNvXsK_Csgsv2Y6Qu5CW_9arbitrarymNtB5_9Arbitrary9size_hintCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXsI_Csgsv2Y6Qu5CW_9arbitraryhNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsK_Csgsv2Y6Qu5CW_9arbitrarymNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsT_Csgsv2Y6Qu5CW_9arbitraryiNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsN_Csgsv2Y6Qu5CW_9arbitraryjNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsL_Csgsv2Y6Qu5CW_9arbitraryyNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsJ_Csgsv2Y6Qu5CW_9arbitrarytNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsM_Csgsv2Y6Qu5CW_9arbitraryoNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsO_Csgsv2Y6Qu5CW_9arbitraryaNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsP_Csgsv2Y6Qu5CW_9arbitrarysNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsQ_Csgsv2Y6Qu5CW_9arbitrarylNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsR_Csgsv2Y6Qu5CW_9arbitraryxNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsS_Csgsv2Y6Qu5CW_9arbitrarynNtB5_9Arbitrary9size_hintB5_
324
325
            }
326
        )*
327
    }
328
}
329
330
impl_arbitrary_for_integers! {
331
    u8: u8;
332
    u16: u16;
333
    u32: u32;
334
    u64: u64;
335
    u128: u128;
336
    usize: usize;
337
    i8: u8;
338
    i16: u16;
339
    i32: u32;
340
    i64: u64;
341
    i128: u128;
342
    isize: usize;
343
}
344
345
macro_rules! impl_arbitrary_for_floats {
346
    ( $( $ty:ident : $unsigned:ty; )* ) => {
347
        $(
348
            impl<'a> Arbitrary<'a> for $ty {
349
2.74k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
350
2.74k
                    Ok(Self::from_bits(<$unsigned as Arbitrary<'a>>::arbitrary(u)?))
351
2.74k
                }
_RNvXsU_Csgsv2Y6Qu5CW_9arbitraryfNtB5_9Arbitrary9arbitrary
Line
Count
Source
349
1.67k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
350
1.67k
                    Ok(Self::from_bits(<$unsigned as Arbitrary<'a>>::arbitrary(u)?))
351
1.67k
                }
_RNvXsV_Csgsv2Y6Qu5CW_9arbitrarydNtB5_9Arbitrary9arbitrary
Line
Count
Source
349
1.06k
                fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
350
1.06k
                    Ok(Self::from_bits(<$unsigned as Arbitrary<'a>>::arbitrary(u)?))
351
1.06k
                }
352
353
                #[inline]
354
0
                fn size_hint(depth: usize) -> (usize, Option<usize>) {
355
0
                    <$unsigned as Arbitrary<'a>>::size_hint(depth)
356
0
                }
Unexecuted instantiation: _RNvXsU_Csgsv2Y6Qu5CW_9arbitraryfNtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXsV_Csgsv2Y6Qu5CW_9arbitrarydNtB5_9Arbitrary9size_hintB5_
357
            }
358
        )*
359
    }
360
}
361
362
impl_arbitrary_for_floats! {
363
    f32: u32;
364
    f64: u64;
365
}
366
367
impl<'a> Arbitrary<'a> for char {
368
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
369
        use std::char;
370
        // The highest unicode code point is 0x11_FFFF
371
        const CHAR_END: u32 = 0x11_0000;
372
        // The size of the surrogate blocks
373
        const SURROGATES_START: u32 = 0xD800;
374
0
        let mut c = <u32 as Arbitrary<'a>>::arbitrary(u)? % CHAR_END;
375
0
        if let Some(c) = char::from_u32(c) {
376
0
            Ok(c)
377
        } else {
378
            // We found a surrogate, wrap and try again
379
0
            c -= SURROGATES_START;
380
0
            Ok(char::from_u32(c)
381
0
                .expect("Generated character should be valid! This is a bug in arbitrary-rs"))
382
        }
383
0
    }
384
385
    #[inline]
386
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
387
0
        <u32 as Arbitrary<'a>>::size_hint(depth)
388
0
    }
389
}
390
391
impl<'a> Arbitrary<'a> for AtomicBool {
392
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
393
0
        Arbitrary::arbitrary(u).map(Self::new)
394
0
    }
395
396
    #[inline]
397
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
398
0
        <bool as Arbitrary<'a>>::size_hint(depth)
399
0
    }
400
}
401
402
impl<'a> Arbitrary<'a> for AtomicIsize {
403
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
404
0
        Arbitrary::arbitrary(u).map(Self::new)
405
0
    }
406
407
    #[inline]
408
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
409
0
        <isize as Arbitrary<'a>>::size_hint(depth)
410
0
    }
411
}
412
413
impl<'a> Arbitrary<'a> for AtomicUsize {
414
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
415
0
        Arbitrary::arbitrary(u).map(Self::new)
416
0
    }
417
418
    #[inline]
419
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
420
0
        <usize as Arbitrary<'a>>::size_hint(depth)
421
0
    }
422
}
423
424
macro_rules! impl_range {
425
    (
426
        $range:ty,
427
        $value_closure:expr,
428
        $value_ty:ty,
429
        $fun:ident($fun_closure:expr),
430
        $size_hint_closure:expr
431
    ) => {
432
        impl<'a, A> Arbitrary<'a> for $range
433
        where
434
            A: Arbitrary<'a> + Clone + PartialOrd,
435
        {
436
0
            fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
437
0
                let value: $value_ty = Arbitrary::arbitrary(u)?;
438
0
                Ok($fun(value, $fun_closure))
439
0
            }
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarysW_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range5RangepENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarysX_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range9RangeFrompENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarysY_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range14RangeInclusivepENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarysZ_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range7RangeTopENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys10_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range16RangeToInclusivepENtB5_9Arbitrary9arbitraryB5_
440
441
            #[inline]
442
0
            fn size_hint(depth: usize) -> (usize, Option<usize>) {
443
0
                #[allow(clippy::redundant_closure_call)]
444
0
                $size_hint_closure(depth)
445
0
            }
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarysW_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range5RangepENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarysX_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range9RangeFrompENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarysY_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range14RangeInclusivepENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarysZ_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range7RangeTopENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys10_0pEINtNtNtCs1ujR1JRCAmI_4core3ops5range16RangeToInclusivepENtB5_9Arbitrary9size_hintB5_
446
        }
447
    };
448
}
449
450
impl_range!(
451
    Range<A>,
452
    |r: &Range<A>| (r.start.clone(), r.end.clone()),
453
    (A, A),
454
0
    bounded_range(|(a, b)| a..b),
455
0
    |depth| crate::size_hint::and(
456
0
        <A as Arbitrary>::size_hint(depth),
457
0
        <A as Arbitrary>::size_hint(depth)
458
0
    )
459
);
460
impl_range!(
461
    RangeFrom<A>,
462
    |r: &RangeFrom<A>| r.start.clone(),
463
    A,
464
0
    unbounded_range(|a| a..),
465
0
    |depth| <A as Arbitrary>::size_hint(depth)
466
);
467
impl_range!(
468
    RangeInclusive<A>,
469
    |r: &RangeInclusive<A>| (r.start().clone(), r.end().clone()),
470
    (A, A),
471
0
    bounded_range(|(a, b)| a..=b),
472
0
    |depth| crate::size_hint::and(
473
0
        <A as Arbitrary>::size_hint(depth),
474
0
        <A as Arbitrary>::size_hint(depth)
475
0
    )
476
);
477
impl_range!(
478
    RangeTo<A>,
479
    |r: &RangeTo<A>| r.end.clone(),
480
    A,
481
0
    unbounded_range(|b| ..b),
482
0
    |depth| <A as Arbitrary>::size_hint(depth)
483
);
484
impl_range!(
485
    RangeToInclusive<A>,
486
    |r: &RangeToInclusive<A>| r.end.clone(),
487
    A,
488
0
    unbounded_range(|b| ..=b),
489
0
    |depth| <A as Arbitrary>::size_hint(depth)
490
);
491
492
0
pub(crate) fn bounded_range<CB, I, R>(bounds: (I, I), cb: CB) -> R
493
0
where
494
0
    CB: Fn((I, I)) -> R,
495
0
    I: PartialOrd,
496
0
    R: RangeBounds<I>,
497
0
{
498
0
    let (mut start, mut end) = bounds;
499
0
    if start > end {
500
0
        mem::swap(&mut start, &mut end);
501
0
    }
502
0
    cb((start, end))
503
0
}
504
505
0
pub(crate) fn unbounded_range<CB, I, R>(bound: I, cb: CB) -> R
506
0
where
507
0
    CB: Fn(I) -> R,
508
0
    R: RangeBounds<I>,
509
0
{
510
0
    cb(bound)
511
0
}
512
513
impl<'a> Arbitrary<'a> for Duration {
514
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
515
0
        Ok(Self::new(
516
0
            <u64 as Arbitrary>::arbitrary(u)?,
517
0
            u.int_in_range(0..=999_999_999)?,
518
        ))
519
0
    }
520
521
    #[inline]
522
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
523
0
        crate::size_hint::and(
524
0
            <u64 as Arbitrary>::size_hint(depth),
525
0
            <u32 as Arbitrary>::size_hint(depth),
526
0
        )
527
0
    }
528
}
529
530
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Option<A> {
531
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
532
0
        Ok(if <bool as Arbitrary<'a>>::arbitrary(u)? {
533
0
            Some(Arbitrary::arbitrary(u)?)
534
        } else {
535
0
            None
536
        })
537
0
    }
538
539
    #[inline]
540
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
541
0
        crate::size_hint::and(
542
0
            <bool as Arbitrary>::size_hint(depth),
543
0
            crate::size_hint::or((0, Some(0)), <A as Arbitrary>::size_hint(depth)),
544
0
        )
545
0
    }
546
}
547
548
impl<'a, A: Arbitrary<'a>, B: Arbitrary<'a>> Arbitrary<'a> for std::result::Result<A, B> {
549
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
550
0
        Ok(if <bool as Arbitrary<'a>>::arbitrary(u)? {
551
0
            Ok(<A as Arbitrary>::arbitrary(u)?)
552
        } else {
553
0
            Err(<B as Arbitrary>::arbitrary(u)?)
554
        })
555
0
    }
556
557
    #[inline]
558
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
559
0
        crate::size_hint::and(
560
0
            <bool as Arbitrary>::size_hint(depth),
561
0
            crate::size_hint::or(
562
0
                <A as Arbitrary>::size_hint(depth),
563
0
                <B as Arbitrary>::size_hint(depth),
564
0
            ),
565
0
        )
566
0
    }
567
}
568
569
macro_rules! arbitrary_tuple {
570
    () => {};
571
    ($last: ident $($xs: ident)*) => {
572
        arbitrary_tuple!($($xs)*);
573
574
        impl<'a, $($xs: Arbitrary<'a>,)* $last: Arbitrary<'a>> Arbitrary<'a> for ($($xs,)* $last,) {
575
0
            fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
576
0
                Ok(($($xs::arbitrary(u)?,)* Arbitrary::arbitrary(u)?,))
577
0
            }
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1q_0pETpENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1p_0ppETppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1o_0pppETpppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1n_0ppppETppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1m_0pppppETpppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1l_0ppppppETppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1k_0pppppppETpppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1j_0ppppppppETppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1i_0pppppppppETpppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1h_0ppppppppppETppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1g_0pppppppppppETpppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1f_0ppppppppppppETppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1e_0pppppppppppppETpppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1d_0ppppppppppppppETppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1c_0pppppppppppppppETpppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1b_0ppppppppppppppppETppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1a_0pppppppppppppppppETpppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys19_0ppppppppppppppppppETppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys18_0pppppppppppppppppppETpppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys17_0ppppppppppppppppppppETppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys16_0pppppppppppppppppppppETpppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys15_0ppppppppppppppppppppppETppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys14_0pppppppppppppppppppppppETpppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys13_0ppppppppppppppppppppppppETppppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys12_0pppppppppppppppppppppppppETpppppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys11_0ppppppppppppppppppppppppppETppppppppppppppppppppppppppENtB5_9Arbitrary9arbitraryB5_
578
579
            #[allow(unused_mut, non_snake_case)]
580
0
            fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
581
0
                $(let $xs = $xs::arbitrary(&mut u)?;)*
582
0
                let $last = $last::arbitrary_take_rest(u)?;
583
0
                Ok(($($xs,)* $last,))
584
0
            }
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1q_0pETpENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1p_0ppETppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1o_0pppETpppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1n_0ppppETppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1m_0pppppETpppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1l_0ppppppETppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1k_0pppppppETpppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1j_0ppppppppETppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1i_0pppppppppETpppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1h_0ppppppppppETppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1g_0pppppppppppETpppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1f_0ppppppppppppETppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1e_0pppppppppppppETpppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1d_0ppppppppppppppETppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1c_0pppppppppppppppETpppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1b_0ppppppppppppppppETppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1a_0pppppppppppppppppETpppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys19_0ppppppppppppppppppETppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys18_0pppppppppppppppppppETpppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys17_0ppppppppppppppppppppETppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys16_0pppppppppppppppppppppETpppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys15_0ppppppppppppppppppppppETppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys14_0pppppppppppppppppppppppETpppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys13_0ppppppppppppppppppppppppETppppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys12_0pppppppppppppppppppppppppETpppppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys11_0ppppppppppppppppppppppppppETppppppppppppppppppppppppppENtB5_9Arbitrary19arbitrary_take_restB5_
585
586
            #[inline]
587
0
            fn size_hint(depth: usize) -> (usize, Option<usize>) {
588
0
                crate::size_hint::and_all(&[
589
0
                    <$last as Arbitrary>::size_hint(depth),
590
0
                    $( <$xs as Arbitrary>::size_hint(depth) ),*
591
0
                ])
592
0
            }
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1q_0pETpENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1p_0ppETppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1o_0pppETpppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1n_0ppppETppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1m_0pppppETpppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1l_0ppppppETppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1k_0pppppppETpppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1j_0ppppppppETppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1i_0pppppppppETpppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1h_0ppppppppppETppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1g_0pppppppppppETpppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1f_0ppppppppppppETppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1e_0pppppppppppppETpppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1d_0ppppppppppppppETppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1c_0pppppppppppppppETpppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1b_0ppppppppppppppppETppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys1a_0pppppppppppppppppETpppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys19_0ppppppppppppppppppETppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys18_0pppppppppppppppppppETpppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys17_0ppppppppppppppppppppETppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys16_0pppppppppppppppppppppETpppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys15_0ppppppppppppppppppppppETppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys14_0pppppppppppppppppppppppETpppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys13_0ppppppppppppppppppppppppETppppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys12_0pppppppppppppppppppppppppETpppppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys11_0ppppppppppppppppppppppppppETppppppppppppppppppppppppppENtB5_9Arbitrary9size_hintB5_
593
        }
594
    };
595
}
596
arbitrary_tuple!(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z);
597
598
// Helper to safely create arrays since the standard library doesn't
599
// provide one yet. Shouldn't be necessary in the future.
600
struct ArrayGuard<T, const N: usize> {
601
    dst: *mut T,
602
    initialized: usize,
603
}
604
605
impl<T, const N: usize> Drop for ArrayGuard<T, N> {
606
0
    fn drop(&mut self) {
607
0
        debug_assert!(self.initialized <= N);
608
0
        let initialized_part = core::ptr::slice_from_raw_parts_mut(self.dst, self.initialized);
609
0
        unsafe {
610
0
            core::ptr::drop_in_place(initialized_part);
611
0
        }
612
0
    }
Unexecuted instantiation: _RNvXs7_Csgsv2Y6Qu5CW_9arbitraryINtB5_10ArrayGuardhKj10_ENtNtNtCs1ujR1JRCAmI_4core3ops4drop4Drop4dropCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys7_0pKpEINtB5_10ArrayGuardpKpENtNtNtCs1ujR1JRCAmI_4core3ops4drop4Drop4dropB5_
613
}
614
615
0
fn try_create_array<F, T, const N: usize>(mut cb: F) -> Result<[T; N]>
616
0
where
617
0
    F: FnMut(usize) -> Result<T>,
618
0
{
619
0
    let mut array: mem::MaybeUninit<[T; N]> = mem::MaybeUninit::uninit();
620
0
    let array_ptr = array.as_mut_ptr();
621
0
    let dst = array_ptr as _;
622
0
    let mut guard: ArrayGuard<T, N> = ArrayGuard {
623
0
        dst,
624
0
        initialized: 0,
625
0
    };
626
    unsafe {
627
0
        for (idx, value_ptr) in (*array.as_mut_ptr()).iter_mut().enumerate() {
628
0
            core::ptr::write(value_ptr, cb(idx)?);
629
0
            guard.initialized += 1;
630
        }
631
0
        mem::forget(guard);
632
0
        Ok(array.assume_init())
633
    }
634
0
}
Unexecuted instantiation: _RINvCsgsv2Y6Qu5CW_9arbitrary16try_create_arrayNCNvXs8_B2_Ahj10_NtB2_9Arbitrary9arbitrary0hKBV_ECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvCsgsv2Y6Qu5CW_9arbitrary16try_create_arrayppKpEB2_
635
636
impl<'a, T, const N: usize> Arbitrary<'a> for [T; N]
637
where
638
    T: Arbitrary<'a>,
639
{
640
    #[inline]
641
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
642
0
        try_create_array(|_| <T as Arbitrary<'a>>::arbitrary(u))
Unexecuted instantiation: _RNCNvXs8_Csgsv2Y6Qu5CW_9arbitraryAhj10_NtB7_9Arbitrary9arbitrary0Cs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNCNvXINICsgsv2Y6Qu5CW_9arbitrarys8_0pKpEAppNtB7_9Arbitrary9arbitrary0B7_
643
0
    }
Unexecuted instantiation: _RNvXs8_Csgsv2Y6Qu5CW_9arbitraryAhj10_NtB5_9Arbitrary9arbitraryCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXINICsgsv2Y6Qu5CW_9arbitrarys8_0pKpEAppNtB5_9Arbitrary9arbitraryB5_
644
645
    #[inline]
646
0
    fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
647
0
        let mut array = Self::arbitrary(&mut u)?;
648
0
        if let Some(last) = array.last_mut() {
649
0
            *last = Arbitrary::arbitrary_take_rest(u)?;
650
0
        }
651
0
        Ok(array)
652
0
    }
653
654
    #[inline]
655
0
    fn size_hint(d: usize) -> (usize, Option<usize>) {
656
0
        crate::size_hint::and_all(&array::from_fn::<_, N, _>(|_| {
657
0
            <T as Arbitrary>::size_hint(d)
658
0
        }))
659
0
    }
660
}
661
662
impl<'a> Arbitrary<'a> for &'a [u8] {
663
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
664
0
        let len = u.arbitrary_len::<u8>()?;
665
0
        u.bytes(len)
666
0
    }
667
668
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
669
0
        Ok(u.take_rest())
670
0
    }
671
672
    #[inline]
673
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
674
0
        (0, None)
675
0
    }
676
}
677
678
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Vec<A> {
679
776
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
680
776
        u.arbitrary_iter()?.collect()
681
776
    }
_RNvXsa_Csgsv2Y6Qu5CW_9arbitraryINtNtCsbpSlAbJY2yh_5alloc3vec3VechENtB5_9Arbitrary9arbitraryCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
679
776
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
680
776
        u.arbitrary_iter()?.collect()
681
776
    }
Unexecuted instantiation: _RNvXsa_Csgsv2Y6Qu5CW_9arbitraryINtNtCsbpSlAbJY2yh_5alloc3vec3VechENtB5_9Arbitrary9arbitraryB5_
682
683
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
684
0
        u.arbitrary_take_rest_iter()?.collect()
685
0
    }
686
687
    #[inline]
688
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
689
0
        (0, None)
690
0
    }
691
}
692
693
impl<'a, K: Arbitrary<'a> + Ord, V: Arbitrary<'a>> Arbitrary<'a> for BTreeMap<K, V> {
694
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
695
0
        u.arbitrary_iter()?.collect()
696
0
    }
697
698
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
699
0
        u.arbitrary_take_rest_iter()?.collect()
700
0
    }
701
702
    #[inline]
703
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
704
0
        (0, None)
705
0
    }
706
}
707
708
impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BTreeSet<A> {
709
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
710
0
        u.arbitrary_iter()?.collect()
711
0
    }
712
713
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
714
0
        u.arbitrary_take_rest_iter()?.collect()
715
0
    }
716
717
    #[inline]
718
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
719
0
        (0, None)
720
0
    }
721
}
722
723
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Bound<A> {
724
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
725
0
        match u.int_in_range::<u8>(0..=2)? {
726
0
            0 => Ok(Bound::Included(A::arbitrary(u)?)),
727
0
            1 => Ok(Bound::Excluded(A::arbitrary(u)?)),
728
0
            2 => Ok(Bound::Unbounded),
729
0
            _ => unreachable!(),
730
        }
731
0
    }
732
733
    #[inline]
734
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
735
0
        size_hint::or(
736
0
            size_hint::and((1, Some(1)), A::size_hint(depth)),
737
0
            (1, Some(1)),
738
0
        )
739
0
    }
740
}
741
742
impl<'a, A: Arbitrary<'a> + Ord> Arbitrary<'a> for BinaryHeap<A> {
743
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
744
0
        u.arbitrary_iter()?.collect()
745
0
    }
746
747
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
748
0
        u.arbitrary_take_rest_iter()?.collect()
749
0
    }
750
751
    #[inline]
752
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
753
0
        (0, None)
754
0
    }
755
}
756
757
impl<'a, K: Arbitrary<'a> + Eq + ::std::hash::Hash, V: Arbitrary<'a>, S: BuildHasher + Default>
758
    Arbitrary<'a> for HashMap<K, V, S>
759
{
760
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
761
0
        u.arbitrary_iter()?.collect()
762
0
    }
763
764
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
765
0
        u.arbitrary_take_rest_iter()?.collect()
766
0
    }
767
768
    #[inline]
769
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
770
0
        (0, None)
771
0
    }
772
}
773
774
impl<'a, A: Arbitrary<'a> + Eq + ::std::hash::Hash, S: BuildHasher + Default> Arbitrary<'a>
775
    for HashSet<A, S>
776
{
777
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
778
0
        u.arbitrary_iter()?.collect()
779
0
    }
780
781
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
782
0
        u.arbitrary_take_rest_iter()?.collect()
783
0
    }
784
785
    #[inline]
786
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
787
0
        (0, None)
788
0
    }
789
}
790
791
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for LinkedList<A> {
792
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
793
0
        u.arbitrary_iter()?.collect()
794
0
    }
795
796
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
797
0
        u.arbitrary_take_rest_iter()?.collect()
798
0
    }
799
800
    #[inline]
801
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
802
0
        (0, None)
803
0
    }
804
}
805
806
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for VecDeque<A> {
807
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
808
0
        u.arbitrary_iter()?.collect()
809
0
    }
810
811
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
812
0
        u.arbitrary_take_rest_iter()?.collect()
813
0
    }
814
815
    #[inline]
816
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
817
0
        (0, None)
818
0
    }
819
}
820
821
impl<'a, A> Arbitrary<'a> for Cow<'a, A>
822
where
823
    A: ToOwned + ?Sized,
824
    <A as ToOwned>::Owned: Arbitrary<'a>,
825
{
826
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
827
0
        Arbitrary::arbitrary(u).map(Cow::Owned)
828
0
    }
829
830
    #[inline]
831
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
832
0
        crate::size_hint::recursion_guard(depth, |depth| {
833
0
            <<A as ToOwned>::Owned as Arbitrary>::size_hint(depth)
834
0
        })
835
0
    }
836
}
837
838
0
fn arbitrary_str<'a>(u: &mut Unstructured<'a>, size: usize) -> Result<&'a str> {
839
0
    match str::from_utf8(u.peek_bytes(size).unwrap()) {
840
0
        Ok(s) => {
841
0
            u.bytes(size).unwrap();
842
0
            Ok(s)
843
        }
844
0
        Err(e) => {
845
0
            let i = e.valid_up_to();
846
0
            let valid = u.bytes(i).unwrap();
847
0
            let s = unsafe {
848
0
                debug_assert!(str::from_utf8(valid).is_ok());
849
0
                str::from_utf8_unchecked(valid)
850
0
            };
851
0
            Ok(s)
852
        }
853
    }
854
0
}
855
856
impl<'a> Arbitrary<'a> for &'a str {
857
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
858
0
        let size = u.arbitrary_len::<u8>()?;
859
0
        arbitrary_str(u, size)
860
0
    }
861
862
0
    fn arbitrary_take_rest(mut u: Unstructured<'a>) -> Result<Self> {
863
0
        let size = u.len();
864
0
        arbitrary_str(&mut u, size)
865
0
    }
866
867
    #[inline]
868
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
869
0
        (0, None)
870
0
    }
871
}
872
873
impl<'a> Arbitrary<'a> for String {
874
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
875
0
        <&str as Arbitrary>::arbitrary(u).map(Into::into)
876
0
    }
877
878
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
879
0
        <&str as Arbitrary>::arbitrary_take_rest(u).map(Into::into)
880
0
    }
881
882
    #[inline]
883
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
884
0
        <&str as Arbitrary>::size_hint(depth)
885
0
    }
886
}
887
888
impl<'a> Arbitrary<'a> for CString {
889
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
890
0
        <Vec<u8> as Arbitrary>::arbitrary(u).map(|mut x| {
891
0
            x.retain(|&c| c != 0);
892
0
            Self::new(x).unwrap()
893
0
        })
894
0
    }
895
896
    #[inline]
897
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
898
0
        <Vec<u8> as Arbitrary>::size_hint(depth)
899
0
    }
900
}
901
902
impl<'a> Arbitrary<'a> for OsString {
903
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
904
0
        <String as Arbitrary>::arbitrary(u).map(From::from)
905
0
    }
906
907
    #[inline]
908
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
909
0
        <String as Arbitrary>::size_hint(depth)
910
0
    }
911
}
912
913
impl<'a> Arbitrary<'a> for PathBuf {
914
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
915
0
        <OsString as Arbitrary>::arbitrary(u).map(From::from)
916
0
    }
917
918
    #[inline]
919
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
920
0
        <OsString as Arbitrary>::size_hint(depth)
921
0
    }
922
}
923
924
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<A> {
925
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
926
0
        Arbitrary::arbitrary(u).map(Self::new)
927
0
    }
928
929
    #[inline]
930
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
931
0
        crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
932
0
    }
933
}
934
935
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Box<[A]> {
936
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
937
0
        u.arbitrary_iter()?.collect()
938
0
    }
939
940
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
941
0
        u.arbitrary_take_rest_iter()?.collect()
942
0
    }
943
944
    #[inline]
945
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
946
0
        (0, None)
947
0
    }
948
}
949
950
impl<'a> Arbitrary<'a> for Box<str> {
951
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
952
0
        <String as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_str())
953
0
    }
954
955
    #[inline]
956
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
957
0
        <String as Arbitrary>::size_hint(depth)
958
0
    }
959
}
960
961
// impl Arbitrary for Box<CStr> {
962
//     fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> {
963
//         <CString as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_c_str())
964
//     }
965
// }
966
967
// impl Arbitrary for Box<OsStr> {
968
//     fn arbitrary(u: &mut Unstructured<'_>) -> Result<Self> {
969
//         <OsString as Arbitrary>::arbitrary(u).map(|x| x.into_boxed_osstr())
970
//
971
//     }
972
// }
973
974
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc<A> {
975
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
976
0
        Arbitrary::arbitrary(u).map(Self::new)
977
0
    }
978
979
    #[inline]
980
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
981
0
        crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
982
0
    }
983
}
984
985
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Arc<[A]> {
986
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
987
0
        u.arbitrary_iter()?.collect()
988
0
    }
989
990
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
991
0
        u.arbitrary_take_rest_iter()?.collect()
992
0
    }
993
994
    #[inline]
995
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
996
0
        (0, None)
997
0
    }
998
}
999
1000
impl<'a> Arbitrary<'a> for Arc<str> {
1001
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1002
0
        <&str as Arbitrary>::arbitrary(u).map(Into::into)
1003
0
    }
1004
1005
    #[inline]
1006
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1007
0
        <&str as Arbitrary>::size_hint(depth)
1008
0
    }
1009
}
1010
1011
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc<A> {
1012
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1013
0
        Arbitrary::arbitrary(u).map(Self::new)
1014
0
    }
1015
1016
    #[inline]
1017
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1018
0
        crate::size_hint::recursion_guard(depth, <A as Arbitrary>::size_hint)
1019
0
    }
1020
}
1021
1022
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Rc<[A]> {
1023
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1024
0
        u.arbitrary_iter()?.collect()
1025
0
    }
1026
1027
0
    fn arbitrary_take_rest(u: Unstructured<'a>) -> Result<Self> {
1028
0
        u.arbitrary_take_rest_iter()?.collect()
1029
0
    }
1030
1031
    #[inline]
1032
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1033
0
        (0, None)
1034
0
    }
1035
}
1036
1037
impl<'a> Arbitrary<'a> for Rc<str> {
1038
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1039
0
        <&str as Arbitrary>::arbitrary(u).map(Into::into)
1040
0
    }
1041
1042
    #[inline]
1043
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1044
0
        <&str as Arbitrary>::size_hint(depth)
1045
0
    }
1046
}
1047
1048
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Cell<A> {
1049
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1050
0
        Arbitrary::arbitrary(u).map(Self::new)
1051
0
    }
1052
1053
    #[inline]
1054
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1055
0
        <A as Arbitrary<'a>>::size_hint(depth)
1056
0
    }
1057
}
1058
1059
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for RefCell<A> {
1060
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1061
0
        Arbitrary::arbitrary(u).map(Self::new)
1062
0
    }
1063
1064
    #[inline]
1065
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1066
0
        <A as Arbitrary<'a>>::size_hint(depth)
1067
0
    }
1068
}
1069
1070
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for UnsafeCell<A> {
1071
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1072
0
        Arbitrary::arbitrary(u).map(Self::new)
1073
0
    }
1074
1075
    #[inline]
1076
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1077
0
        <A as Arbitrary<'a>>::size_hint(depth)
1078
0
    }
1079
}
1080
1081
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for Mutex<A> {
1082
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1083
0
        Arbitrary::arbitrary(u).map(Self::new)
1084
0
    }
1085
1086
    #[inline]
1087
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1088
0
        <A as Arbitrary<'a>>::size_hint(depth)
1089
0
    }
1090
}
1091
1092
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for iter::Empty<A> {
1093
0
    fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
1094
0
        Ok(iter::empty())
1095
0
    }
1096
1097
    #[inline]
1098
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1099
0
        (0, Some(0))
1100
0
    }
1101
}
1102
1103
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::marker::PhantomData<A> {
1104
0
    fn arbitrary(_: &mut Unstructured<'a>) -> Result<Self> {
1105
0
        Ok(::std::marker::PhantomData)
1106
0
    }
1107
1108
    #[inline]
1109
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1110
0
        (0, Some(0))
1111
0
    }
1112
}
1113
1114
impl<'a, A: Arbitrary<'a>> Arbitrary<'a> for ::std::num::Wrapping<A> {
1115
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1116
0
        Arbitrary::arbitrary(u).map(::std::num::Wrapping)
1117
0
    }
1118
1119
    #[inline]
1120
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1121
0
        <A as Arbitrary<'a>>::size_hint(depth)
1122
0
    }
1123
}
1124
1125
macro_rules! implement_nonzero_int {
1126
    ($nonzero:ty, $int:ty) => {
1127
        impl<'a> Arbitrary<'a> for $nonzero {
1128
0
            fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1129
0
                match Self::new(<$int as Arbitrary<'a>>::arbitrary(u)?) {
1130
0
                    Some(n) => Ok(n),
1131
0
                    None => Err(Error::IncorrectFormat),
1132
                }
1133
0
            }
Unexecuted instantiation: _RNvXs1r_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroaENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1s_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerosENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1t_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerolENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1u_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroxENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1v_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeronENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1w_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroiENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1x_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerohENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1y_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerotENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1z_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeromENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1A_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroyENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1B_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerooENtB6_9Arbitrary9arbitrary
Unexecuted instantiation: _RNvXs1C_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerojENtB6_9Arbitrary9arbitrary
1134
1135
            #[inline]
1136
0
            fn size_hint(depth: usize) -> (usize, Option<usize>) {
1137
0
                <$int as Arbitrary<'a>>::size_hint(depth)
1138
0
            }
Unexecuted instantiation: _RNvXs1r_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroaENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1s_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerosENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1t_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerolENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1u_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroxENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1v_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeronENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1w_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroiENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1x_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerohENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1y_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerotENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1z_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeromENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1A_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZeroyENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1B_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerooENtB6_9Arbitrary9size_hintB6_
Unexecuted instantiation: _RNvXs1C_Csgsv2Y6Qu5CW_9arbitraryINtNtNtCs1ujR1JRCAmI_4core3num7nonzero7NonZerojENtB6_9Arbitrary9size_hintB6_
1139
        }
1140
    };
1141
}
1142
1143
implement_nonzero_int! { NonZeroI8, i8 }
1144
implement_nonzero_int! { NonZeroI16, i16 }
1145
implement_nonzero_int! { NonZeroI32, i32 }
1146
implement_nonzero_int! { NonZeroI64, i64 }
1147
implement_nonzero_int! { NonZeroI128, i128 }
1148
implement_nonzero_int! { NonZeroIsize, isize }
1149
implement_nonzero_int! { NonZeroU8, u8 }
1150
implement_nonzero_int! { NonZeroU16, u16 }
1151
implement_nonzero_int! { NonZeroU32, u32 }
1152
implement_nonzero_int! { NonZeroU64, u64 }
1153
implement_nonzero_int! { NonZeroU128, u128 }
1154
implement_nonzero_int! { NonZeroUsize, usize }
1155
1156
impl<'a> Arbitrary<'a> for Ipv4Addr {
1157
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1158
0
        Ok(Ipv4Addr::from(u32::arbitrary(u)?))
1159
0
    }
1160
1161
    #[inline]
1162
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1163
0
        (4, Some(4))
1164
0
    }
1165
}
1166
1167
impl<'a> Arbitrary<'a> for Ipv6Addr {
1168
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1169
0
        Ok(Ipv6Addr::from(u128::arbitrary(u)?))
1170
0
    }
1171
1172
    #[inline]
1173
0
    fn size_hint(_depth: usize) -> (usize, Option<usize>) {
1174
0
        (16, Some(16))
1175
0
    }
1176
}
1177
1178
impl<'a> Arbitrary<'a> for IpAddr {
1179
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1180
0
        if u.arbitrary()? {
1181
0
            Ok(IpAddr::V4(u.arbitrary()?))
1182
        } else {
1183
0
            Ok(IpAddr::V6(u.arbitrary()?))
1184
        }
1185
0
    }
1186
1187
0
    fn size_hint(depth: usize) -> (usize, Option<usize>) {
1188
0
        size_hint::and(
1189
0
            bool::size_hint(depth),
1190
0
            size_hint::or(Ipv4Addr::size_hint(depth), Ipv6Addr::size_hint(depth)),
1191
0
        )
1192
0
    }
1193
}
1194
1195
#[cfg(test)]
1196
mod test {
1197
    use super::*;
1198
1199
    /// Assert that the given expected values are all generated.
1200
    ///
1201
    /// Exhaustively enumerates all buffers up to length 10 containing the
1202
    /// following bytes: `0x00`, `0x01`, `0x61` (aka ASCII 'a'), and `0xff`
1203
    fn assert_generates<T>(expected_values: impl IntoIterator<Item = T>)
1204
    where
1205
        T: Clone + std::fmt::Debug + std::hash::Hash + Eq + for<'a> Arbitrary<'a>,
1206
    {
1207
        let expected_values: HashSet<_> = expected_values.into_iter().collect();
1208
        let mut arbitrary_expected = expected_values.clone();
1209
        let mut arbitrary_take_rest_expected = expected_values;
1210
1211
        let bytes = [0, 1, b'a', 0xff];
1212
        let max_len = 10;
1213
1214
        let mut buf = Vec::with_capacity(max_len);
1215
1216
        let mut g = exhaustigen::Gen::new();
1217
        while !g.done() {
1218
            let len = g.gen(max_len);
1219
1220
            buf.clear();
1221
            buf.extend(
1222
                std::iter::repeat_with(|| {
1223
                    let index = g.gen(bytes.len() - 1);
1224
                    bytes[index]
1225
                })
1226
                .take(len),
1227
            );
1228
1229
            let mut u = Unstructured::new(&buf);
1230
            let val = T::arbitrary(&mut u).unwrap();
1231
            arbitrary_expected.remove(&val);
1232
1233
            let u = Unstructured::new(&buf);
1234
            let val = T::arbitrary_take_rest(u).unwrap();
1235
            arbitrary_take_rest_expected.remove(&val);
1236
1237
            if arbitrary_expected.is_empty() && arbitrary_take_rest_expected.is_empty() {
1238
                return;
1239
            }
1240
        }
1241
1242
        panic!(
1243
            "failed to generate all expected values!\n\n\
1244
             T::arbitrary did not generate: {arbitrary_expected:#?}\n\n\
1245
             T::arbitrary_take_rest did not generate {arbitrary_take_rest_expected:#?}"
1246
        )
1247
    }
1248
1249
    /// Generates an arbitrary `T`, and checks that the result is consistent with the
1250
    /// `size_hint()` reported by `T`.
1251
    fn checked_arbitrary<'a, T: Arbitrary<'a>>(u: &mut Unstructured<'a>) -> Result<T> {
1252
        let (min, max) = T::size_hint(0);
1253
1254
        let len_before = u.len();
1255
        let result = T::arbitrary(u);
1256
1257
        let consumed = len_before - u.len();
1258
1259
        if let Some(max) = max {
1260
            assert!(
1261
                consumed <= max,
1262
                "incorrect maximum size: indicated {}, actually consumed {}",
1263
                max,
1264
                consumed
1265
            );
1266
        }
1267
1268
        if result.is_ok() {
1269
            assert!(
1270
                consumed >= min,
1271
                "incorrect minimum size: indicated {}, actually consumed {}",
1272
                min,
1273
                consumed
1274
            );
1275
        }
1276
1277
        result
1278
    }
1279
1280
    /// Like `checked_arbitrary()`, but calls `arbitrary_take_rest()` instead of `arbitrary()`.
1281
    fn checked_arbitrary_take_rest<'a, T: Arbitrary<'a>>(u: Unstructured<'a>) -> Result<T> {
1282
        let (min, _) = T::size_hint(0);
1283
1284
        let len_before = u.len();
1285
        let result = T::arbitrary_take_rest(u);
1286
1287
        if result.is_ok() {
1288
            assert!(
1289
                len_before >= min,
1290
                "incorrect minimum size: indicated {}, worked with {}",
1291
                min,
1292
                len_before
1293
            );
1294
        }
1295
1296
        result
1297
    }
1298
1299
    #[test]
1300
    fn finite_buffer_fill_buffer() {
1301
        let x = [1, 2, 3, 4];
1302
        let mut rb = Unstructured::new(&x);
1303
        let mut z = [0; 2];
1304
        rb.fill_buffer(&mut z).unwrap();
1305
        assert_eq!(z, [1, 2]);
1306
        rb.fill_buffer(&mut z).unwrap();
1307
        assert_eq!(z, [3, 4]);
1308
        rb.fill_buffer(&mut z).unwrap();
1309
        assert_eq!(z, [0, 0]);
1310
    }
1311
1312
    #[test]
1313
    fn arbitrary_for_integers() {
1314
        let x = [1, 2, 3, 4];
1315
        let mut buf = Unstructured::new(&x);
1316
        let expected = 1 | (2 << 8) | (3 << 16) | (4 << 24);
1317
        let actual = checked_arbitrary::<i32>(&mut buf).unwrap();
1318
        assert_eq!(expected, actual);
1319
1320
        assert_generates([
1321
            i32::from_ne_bytes([0, 0, 0, 0]),
1322
            i32::from_ne_bytes([0, 0, 0, 1]),
1323
            i32::from_ne_bytes([0, 0, 1, 0]),
1324
            i32::from_ne_bytes([0, 1, 0, 0]),
1325
            i32::from_ne_bytes([1, 0, 0, 0]),
1326
            i32::from_ne_bytes([1, 1, 1, 1]),
1327
            i32::from_ne_bytes([0xff, 0xff, 0xff, 0xff]),
1328
        ]);
1329
    }
1330
1331
    #[test]
1332
    fn arbitrary_for_bytes() {
1333
        let x = [1, 2, 3, 4, 4];
1334
        let mut buf = Unstructured::new(&x);
1335
        let expected = &[1, 2, 3, 4];
1336
        let actual = checked_arbitrary::<&[u8]>(&mut buf).unwrap();
1337
        assert_eq!(expected, actual);
1338
    }
1339
1340
    #[test]
1341
    fn arbitrary_take_rest_for_bytes() {
1342
        let x = [1, 2, 3, 4];
1343
        let buf = Unstructured::new(&x);
1344
        let expected = &[1, 2, 3, 4];
1345
        let actual = checked_arbitrary_take_rest::<&[u8]>(buf).unwrap();
1346
        assert_eq!(expected, actual);
1347
    }
1348
1349
    #[test]
1350
    fn arbitrary_for_vec_u8() {
1351
        assert_generates::<Vec<u8>>([
1352
            vec![],
1353
            vec![0],
1354
            vec![1],
1355
            vec![0, 0],
1356
            vec![0, 1],
1357
            vec![1, 0],
1358
            vec![1, 1],
1359
            vec![0, 0, 0],
1360
            vec![0, 0, 1],
1361
            vec![0, 1, 0],
1362
            vec![0, 1, 1],
1363
            vec![1, 0, 0],
1364
            vec![1, 0, 1],
1365
            vec![1, 1, 0],
1366
            vec![1, 1, 1],
1367
        ]);
1368
    }
1369
1370
    #[test]
1371
    fn arbitrary_for_vec_vec_u8() {
1372
        assert_generates::<Vec<Vec<u8>>>([
1373
            vec![],
1374
            vec![vec![]],
1375
            vec![vec![0]],
1376
            vec![vec![1]],
1377
            vec![vec![0, 1]],
1378
            vec![vec![], vec![]],
1379
            vec![vec![0], vec![]],
1380
            vec![vec![], vec![1]],
1381
            vec![vec![0], vec![1]],
1382
            vec![vec![0, 1], vec![]],
1383
            vec![vec![], vec![1, 0]],
1384
            vec![vec![], vec![], vec![]],
1385
        ]);
1386
    }
1387
1388
    #[test]
1389
    fn arbitrary_for_vec_vec_vec_u8() {
1390
        assert_generates::<Vec<Vec<Vec<u8>>>>([
1391
            vec![],
1392
            vec![vec![]],
1393
            vec![vec![vec![0]]],
1394
            vec![vec![vec![1]]],
1395
            vec![vec![vec![0, 1]]],
1396
            vec![vec![], vec![]],
1397
            vec![vec![], vec![vec![]]],
1398
            vec![vec![vec![]], vec![]],
1399
            vec![vec![vec![]], vec![vec![]]],
1400
            vec![vec![vec![0]], vec![]],
1401
            vec![vec![], vec![vec![1]]],
1402
            vec![vec![vec![0]], vec![vec![1]]],
1403
            vec![vec![vec![0, 1]], vec![]],
1404
            vec![vec![], vec![vec![0, 1]]],
1405
            vec![vec![], vec![], vec![]],
1406
            vec![vec![vec![]], vec![], vec![]],
1407
            vec![vec![], vec![vec![]], vec![]],
1408
            vec![vec![], vec![], vec![vec![]]],
1409
        ]);
1410
    }
1411
1412
    #[test]
1413
    fn arbitrary_for_string() {
1414
        assert_generates::<String>(["".into(), "a".into(), "aa".into(), "aaa".into()]);
1415
    }
1416
1417
    #[test]
1418
    fn arbitrary_collection() {
1419
        let x = [
1420
            1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 12,
1421
        ];
1422
        assert_eq!(
1423
            checked_arbitrary::<&[u8]>(&mut Unstructured::new(&x)).unwrap(),
1424
            &[1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3]
1425
        );
1426
        assert_eq!(
1427
            checked_arbitrary::<Vec<u8>>(&mut Unstructured::new(&x)).unwrap(),
1428
            &[2, 4, 6, 8, 1]
1429
        );
1430
        assert_eq!(
1431
            &*checked_arbitrary::<Box<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
1432
            &[2, 4, 6, 8, 1]
1433
        );
1434
        assert_eq!(
1435
            &*checked_arbitrary::<Arc<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
1436
            &[2, 4, 6, 8, 1]
1437
        );
1438
        assert_eq!(
1439
            &*checked_arbitrary::<Rc<[u8]>>(&mut Unstructured::new(&x)).unwrap(),
1440
            &[2, 4, 6, 8, 1]
1441
        );
1442
        assert_eq!(
1443
            checked_arbitrary::<Vec<u32>>(&mut Unstructured::new(&x)).unwrap(),
1444
            &[84148994]
1445
        );
1446
        assert_eq!(
1447
            checked_arbitrary::<String>(&mut Unstructured::new(&x)).unwrap(),
1448
            "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x01\x02\x03"
1449
        );
1450
    }
1451
1452
    #[test]
1453
    fn arbitrary_take_rest() {
1454
        // Basic examples
1455
        let x = [1, 2, 3, 4];
1456
        assert_eq!(
1457
            checked_arbitrary_take_rest::<&[u8]>(Unstructured::new(&x)).unwrap(),
1458
            &[1, 2, 3, 4]
1459
        );
1460
        assert_eq!(
1461
            checked_arbitrary_take_rest::<Vec<u8>>(Unstructured::new(&x)).unwrap(),
1462
            &[2, 4]
1463
        );
1464
        assert_eq!(
1465
            &*checked_arbitrary_take_rest::<Box<[u8]>>(Unstructured::new(&x)).unwrap(),
1466
            &[2, 4]
1467
        );
1468
        assert_eq!(
1469
            &*checked_arbitrary_take_rest::<Arc<[u8]>>(Unstructured::new(&x)).unwrap(),
1470
            &[2, 4]
1471
        );
1472
        assert_eq!(
1473
            &*checked_arbitrary_take_rest::<Rc<[u8]>>(Unstructured::new(&x)).unwrap(),
1474
            &[2, 4]
1475
        );
1476
        assert_eq!(
1477
            checked_arbitrary_take_rest::<Vec<u32>>(Unstructured::new(&x)).unwrap(),
1478
            &[0x040302]
1479
        );
1480
        assert_eq!(
1481
            checked_arbitrary_take_rest::<String>(Unstructured::new(&x)).unwrap(),
1482
            "\x01\x02\x03\x04"
1483
        );
1484
1485
        // Empty remainder
1486
        assert_eq!(
1487
            checked_arbitrary_take_rest::<&[u8]>(Unstructured::new(&[])).unwrap(),
1488
            &[]
1489
        );
1490
        assert_eq!(
1491
            checked_arbitrary_take_rest::<Vec<u8>>(Unstructured::new(&[])).unwrap(),
1492
            &[]
1493
        );
1494
1495
        // Cannot consume all but can consume part of the input
1496
        assert_eq!(
1497
            checked_arbitrary_take_rest::<String>(Unstructured::new(&[1, 0xFF, 2])).unwrap(),
1498
            "\x01"
1499
        );
1500
    }
1501
1502
    #[test]
1503
    fn size_hint_for_tuples() {
1504
        assert_eq!(
1505
            (7, Some(7)),
1506
            <(bool, u16, i32) as Arbitrary<'_>>::size_hint(0)
1507
        );
1508
        assert_eq!((1, None), <(u8, Vec<u8>) as Arbitrary>::size_hint(0));
1509
    }
1510
}
1511
1512
/// Multiple conflicting arbitrary attributes are used on the same field:
1513
/// ```compile_fail
1514
/// #[derive(::arbitrary::Arbitrary)]
1515
/// struct Point {
1516
///     #[arbitrary(value = 2)]
1517
///     #[arbitrary(value = 2)]
1518
///     x: i32,
1519
/// }
1520
/// ```
1521
///
1522
/// An unknown attribute:
1523
/// ```compile_fail
1524
/// #[derive(::arbitrary::Arbitrary)]
1525
/// struct Point {
1526
///     #[arbitrary(unknown_attr)]
1527
///     x: i32,
1528
/// }
1529
/// ```
1530
///
1531
/// An unknown attribute with a value:
1532
/// ```compile_fail
1533
/// #[derive(::arbitrary::Arbitrary)]
1534
/// struct Point {
1535
///     #[arbitrary(unknown_attr = 13)]
1536
///     x: i32,
1537
/// }
1538
/// ```
1539
///
1540
/// `value` without RHS:
1541
/// ```compile_fail
1542
/// #[derive(::arbitrary::Arbitrary)]
1543
/// struct Point {
1544
///     #[arbitrary(value)]
1545
///     x: i32,
1546
/// }
1547
/// ```
1548
///
1549
/// `with` without RHS:
1550
/// ```compile_fail
1551
/// #[derive(::arbitrary::Arbitrary)]
1552
/// struct Point {
1553
///     #[arbitrary(with)]
1554
///     x: i32,
1555
/// }
1556
/// ```
1557
///
1558
/// Multiple conflicting bounds at the container-level:
1559
/// ```compile_fail
1560
/// #[derive(::arbitrary::Arbitrary)]
1561
/// #[arbitrary(bound = "T: Default")]
1562
/// #[arbitrary(bound = "T: Default")]
1563
/// struct Point<T: Default> {
1564
///     #[arbitrary(default)]
1565
///     x: T,
1566
/// }
1567
/// ```
1568
///
1569
/// Multiple conflicting bounds in a single bound attribute:
1570
/// ```compile_fail
1571
/// #[derive(::arbitrary::Arbitrary)]
1572
/// #[arbitrary(bound = "T: Default, T: Default")]
1573
/// struct Point<T: Default> {
1574
///     #[arbitrary(default)]
1575
///     x: T,
1576
/// }
1577
/// ```
1578
///
1579
/// Multiple conflicting bounds in multiple bound attributes:
1580
/// ```compile_fail
1581
/// #[derive(::arbitrary::Arbitrary)]
1582
/// #[arbitrary(bound = "T: Default", bound = "T: Default")]
1583
/// struct Point<T: Default> {
1584
///     #[arbitrary(default)]
1585
///     x: T,
1586
/// }
1587
/// ```
1588
///
1589
/// Too many bounds supplied:
1590
/// ```compile_fail
1591
/// #[derive(::arbitrary::Arbitrary)]
1592
/// #[arbitrary(bound = "T: Default")]
1593
/// struct Point {
1594
///     x: i32,
1595
/// }
1596
/// ```
1597
///
1598
/// Too many bounds supplied across multiple attributes:
1599
/// ```compile_fail
1600
/// #[derive(::arbitrary::Arbitrary)]
1601
/// #[arbitrary(bound = "T: Default")]
1602
/// #[arbitrary(bound = "U: Default")]
1603
/// struct Point<T: Default> {
1604
///     #[arbitrary(default)]
1605
///     x: T,
1606
/// }
1607
/// ```
1608
#[cfg(all(doctest, feature = "derive"))]
1609
pub struct CompileFailTests;
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.3.2/src/size_hint.rs
Line
Count
Source (jump to first uncovered line)
1
//! Utilities for working with and combining the results of
2
//! [`Arbitrary::size_hint`][crate::Arbitrary::size_hint].
3
4
/// Protects against potential infinite recursion when calculating size hints
5
/// due to indirect type recursion.
6
///
7
/// When the depth is not too deep, calls `f` with `depth + 1` to calculate the
8
/// size hint.
9
///
10
/// Otherwise, returns the default size hint: `(0, None)`.
11
#[inline]
12
0
pub fn recursion_guard(
13
0
    depth: usize,
14
0
    f: impl FnOnce(usize) -> (usize, Option<usize>),
15
0
) -> (usize, Option<usize>) {
16
0
    const MAX_DEPTH: usize = 20;
17
0
    if depth > MAX_DEPTH {
18
0
        (0, None)
19
    } else {
20
0
        f(depth + 1)
21
    }
22
0
}
Unexecuted instantiation: _RINvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint15recursion_guardNCNvXNvNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtB16_6Module17arbitrary_valtype1__NtB10_12ValTypeClassNtB4_9Arbitrary9size_hint0EB18_
Unexecuted instantiation: _RINvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint15recursion_guardpEB4_
23
24
/// Take the sum of the `lhs` and `rhs` size hints.
25
#[inline]
26
0
pub fn and(lhs: (usize, Option<usize>), rhs: (usize, Option<usize>)) -> (usize, Option<usize>) {
27
0
    let lower = lhs.0 + rhs.0;
28
0
    let upper = lhs.1.and_then(|lhs| rhs.1.map(|rhs| lhs + rhs));
Unexecuted instantiation: _RNCNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint3and0Cs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNCNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint3and0B5_
Unexecuted instantiation: _RNCNCNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint3and00Cs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNCNCNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint3and00B7_
29
0
    (lower, upper)
30
0
}
Unexecuted instantiation: _RNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint3andCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint3andB3_
31
32
/// Take the sum of all of the given size hints.
33
///
34
/// If `hints` is empty, returns `(0, Some(0))`, aka the size of consuming
35
/// nothing.
36
#[inline]
37
0
pub fn and_all(hints: &[(usize, Option<usize>)]) -> (usize, Option<usize>) {
38
0
    hints.iter().copied().fold((0, Some(0)), and)
39
0
}
Unexecuted instantiation: _RNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint7and_allCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint7and_allB3_
40
41
/// Take the minimum of the lower bounds and maximum of the upper bounds in the
42
/// `lhs` and `rhs` size hints.
43
#[inline]
44
0
pub fn or(lhs: (usize, Option<usize>), rhs: (usize, Option<usize>)) -> (usize, Option<usize>) {
45
0
    let lower = std::cmp::min(lhs.0, rhs.0);
46
0
    let upper = lhs
47
0
        .1
48
0
        .and_then(|lhs| rhs.1.map(|rhs| std::cmp::max(lhs, rhs)));
Unexecuted instantiation: _RNCNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint2or0Cs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNCNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint2or0B5_
Unexecuted instantiation: _RNCNCNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint2or00Cs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNCNCNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint2or00B7_
49
0
    (lower, upper)
50
0
}
Unexecuted instantiation: _RNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint2orCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint2orB3_
51
52
/// Take the maximum of the `lhs` and `rhs` size hints.
53
///
54
/// If `hints` is empty, returns `(0, Some(0))`, aka the size of consuming
55
/// nothing.
56
#[inline]
57
0
pub fn or_all(hints: &[(usize, Option<usize>)]) -> (usize, Option<usize>) {
58
0
    if let Some(head) = hints.first().copied() {
59
0
        hints[1..].iter().copied().fold(head, or)
60
    } else {
61
0
        (0, Some(0))
62
    }
63
0
}
Unexecuted instantiation: _RNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint6or_allCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvNtCsgsv2Y6Qu5CW_9arbitrary9size_hint6or_allB3_
64
65
#[cfg(test)]
66
mod tests {
67
    #[test]
68
    fn and() {
69
        assert_eq!((5, Some(5)), super::and((2, Some(2)), (3, Some(3))));
70
        assert_eq!((5, None), super::and((2, Some(2)), (3, None)));
71
        assert_eq!((5, None), super::and((2, None), (3, Some(3))));
72
        assert_eq!((5, None), super::and((2, None), (3, None)));
73
    }
74
75
    #[test]
76
    fn or() {
77
        assert_eq!((2, Some(3)), super::or((2, Some(2)), (3, Some(3))));
78
        assert_eq!((2, None), super::or((2, Some(2)), (3, None)));
79
        assert_eq!((2, None), super::or((2, None), (3, Some(3))));
80
        assert_eq!((2, None), super::or((2, None), (3, None)));
81
    }
82
83
    #[test]
84
    fn and_all() {
85
        assert_eq!((0, Some(0)), super::and_all(&[]));
86
        assert_eq!(
87
            (7, Some(7)),
88
            super::and_all(&[(1, Some(1)), (2, Some(2)), (4, Some(4))])
89
        );
90
        assert_eq!(
91
            (7, None),
92
            super::and_all(&[(1, Some(1)), (2, Some(2)), (4, None)])
93
        );
94
        assert_eq!(
95
            (7, None),
96
            super::and_all(&[(1, Some(1)), (2, None), (4, Some(4))])
97
        );
98
        assert_eq!(
99
            (7, None),
100
            super::and_all(&[(1, None), (2, Some(2)), (4, Some(4))])
101
        );
102
    }
103
104
    #[test]
105
    fn or_all() {
106
        assert_eq!((0, Some(0)), super::or_all(&[]));
107
        assert_eq!(
108
            (1, Some(4)),
109
            super::or_all(&[(1, Some(1)), (2, Some(2)), (4, Some(4))])
110
        );
111
        assert_eq!(
112
            (1, None),
113
            super::or_all(&[(1, Some(1)), (2, Some(2)), (4, None)])
114
        );
115
        assert_eq!(
116
            (1, None),
117
            super::or_all(&[(1, Some(1)), (2, None), (4, Some(4))])
118
        );
119
        assert_eq!(
120
            (1, None),
121
            super::or_all(&[(1, None), (2, Some(2)), (4, Some(4))])
122
        );
123
    }
124
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arbitrary-1.3.2/src/unstructured.rs
Line
Count
Source (jump to first uncovered line)
1
// Copyright © 2019 The Rust Fuzz Project Developers.
2
//
3
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
4
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
5
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
6
// option. This file may not be copied, modified, or distributed
7
// except according to those terms.
8
9
//! Wrappers around raw, unstructured bytes.
10
11
use crate::{Arbitrary, Error, Result};
12
use std::marker::PhantomData;
13
use std::ops::ControlFlow;
14
use std::{mem, ops};
15
16
/// A source of unstructured data.
17
///
18
/// An `Unstructured` helps `Arbitrary` implementations interpret raw data
19
/// (typically provided by a fuzzer) as a "DNA string" that describes how to
20
/// construct the `Arbitrary` type. The goal is that a small change to the "DNA
21
/// string" (the raw data wrapped by an `Unstructured`) results in a small
22
/// change to the generated `Arbitrary` instance. This helps a fuzzer
23
/// efficiently explore the `Arbitrary`'s input space.
24
///
25
/// `Unstructured` is deterministic: given the same raw data, the same series of
26
/// API calls will return the same results (modulo system resource constraints,
27
/// like running out of memory). However, `Unstructured` does not guarantee
28
/// anything beyond that: it makes not guarantee that it will yield bytes from
29
/// the underlying data in any particular order.
30
///
31
/// You shouldn't generally need to use an `Unstructured` unless you are writing
32
/// a custom `Arbitrary` implementation by hand, instead of deriving it. Mostly,
33
/// you should just be passing it through to nested `Arbitrary::arbitrary`
34
/// calls.
35
///
36
/// # Example
37
///
38
/// Imagine you were writing a color conversion crate. You might want to write
39
/// fuzz tests that take a random RGB color and assert various properties, run
40
/// functions and make sure nothing panics, etc.
41
///
42
/// Below is what translating the fuzzer's raw input into an `Unstructured` and
43
/// using that to generate an arbitrary RGB color might look like:
44
///
45
/// ```
46
/// # #[cfg(feature = "derive")] fn foo() {
47
/// use arbitrary::{Arbitrary, Unstructured};
48
///
49
/// /// An RGB color.
50
/// #[derive(Arbitrary)]
51
/// pub struct Rgb {
52
///     r: u8,
53
///     g: u8,
54
///     b: u8,
55
/// }
56
///
57
/// // Get the raw bytes from the fuzzer.
58
/// #   let get_input_from_fuzzer = || &[];
59
/// let raw_data: &[u8] = get_input_from_fuzzer();
60
///
61
/// // Wrap it in an `Unstructured`.
62
/// let mut unstructured = Unstructured::new(raw_data);
63
///
64
/// // Generate an `Rgb` color and run our checks.
65
/// if let Ok(rgb) = Rgb::arbitrary(&mut unstructured) {
66
/// #   let run_my_color_conversion_checks = |_| {};
67
///     run_my_color_conversion_checks(rgb);
68
/// }
69
/// # }
70
/// ```
71
pub struct Unstructured<'a> {
72
    data: &'a [u8],
73
}
74
75
impl<'a> Unstructured<'a> {
76
    /// Create a new `Unstructured` from the given raw data.
77
    ///
78
    /// # Example
79
    ///
80
    /// ```
81
    /// use arbitrary::Unstructured;
82
    ///
83
    /// let u = Unstructured::new(&[1, 2, 3, 4]);
84
    /// ```
85
5.67k
    pub fn new(data: &'a [u8]) -> Self {
86
5.67k
        Unstructured { data }
87
5.67k
    }
_RNvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB2_12Unstructured3newCs5HNiFFfDLPG_6decode
Line
Count
Source
85
5.67k
    pub fn new(data: &'a [u8]) -> Self {
86
5.67k
        Unstructured { data }
87
5.67k
    }
Unexecuted instantiation: _RNvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB2_12Unstructured3newB4_
88
89
    /// Get the number of remaining bytes of underlying data that are still
90
    /// available.
91
    ///
92
    /// # Example
93
    ///
94
    /// ```
95
    /// use arbitrary::{Arbitrary, Unstructured};
96
    ///
97
    /// let mut u = Unstructured::new(&[1, 2, 3]);
98
    ///
99
    /// // Initially have three bytes of data.
100
    /// assert_eq!(u.len(), 3);
101
    ///
102
    /// // Generating a `bool` consumes one byte from the underlying data, so
103
    /// // we are left with two bytes afterwards.
104
    /// let _ = bool::arbitrary(&mut u);
105
    /// assert_eq!(u.len(), 2);
106
    /// ```
107
    #[inline]
108
16.2k
    pub fn len(&self) -> usize {
109
16.2k
        self.data.len()
110
16.2k
    }
_RNvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB2_12Unstructured3lenCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
108
16.2k
    pub fn len(&self) -> usize {
109
16.2k
        self.data.len()
110
16.2k
    }
Unexecuted instantiation: _RNvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB2_12Unstructured3lenB4_
111
112
    /// Is the underlying unstructured data exhausted?
113
    ///
114
    /// `unstructured.is_empty()` is the same as `unstructured.len() == 0`.
115
    ///
116
    /// # Example
117
    ///
118
    /// ```
119
    /// use arbitrary::{Arbitrary, Unstructured};
120
    ///
121
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
122
    ///
123
    /// // Initially, we are not empty.
124
    /// assert!(!u.is_empty());
125
    ///
126
    /// // Generating a `u32` consumes all four bytes of the underlying data, so
127
    /// // we become empty afterwards.
128
    /// let _ = u32::arbitrary(&mut u);
129
    /// assert!(u.is_empty());
130
    /// ```
131
    #[inline]
132
16.2k
    pub fn is_empty(&self) -> bool {
133
16.2k
        self.len() == 0
134
16.2k
    }
_RNvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB2_12Unstructured8is_emptyCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
132
16.2k
    pub fn is_empty(&self) -> bool {
133
16.2k
        self.len() == 0
134
16.2k
    }
Unexecuted instantiation: _RNvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB2_12Unstructured8is_emptyB4_
135
136
    /// Generate an arbitrary instance of `A`.
137
    ///
138
    /// This is simply a helper method that is equivalent to `<A as
139
    /// Arbitrary>::arbitrary(self)`. This helper is a little bit more concise,
140
    /// and can be used in situations where Rust's type inference will figure
141
    /// out what `A` should be.
142
    ///
143
    /// # Example
144
    ///
145
    /// ```
146
    /// # #[cfg(feature="derive")] fn foo() -> arbitrary::Result<()> {
147
    /// use arbitrary::{Arbitrary, Unstructured};
148
    ///
149
    /// #[derive(Arbitrary)]
150
    /// struct MyType {
151
    ///     // ...
152
    /// }
153
    ///
154
    /// fn do_stuff(value: MyType) {
155
    /// #   let _ = value;
156
    ///     // ...
157
    /// }
158
    ///
159
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
160
    ///
161
    /// // Rust's type inference can figure out that `value` should be of type
162
    /// // `MyType` here:
163
    /// let value = u.arbitrary()?;
164
    /// do_stuff(value);
165
    /// # Ok(()) }
166
    /// ```
167
275k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
275k
    where
169
275k
        A: Arbitrary<'a>,
170
275k
    {
171
275k
        <A as Arbitrary<'a>>::arbitrary(self)
172
275k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitrarybECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
167
149k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
149k
    where
169
149k
        A: Arbitrary<'a>,
170
149k
    {
171
149k
        <A as Arbitrary<'a>>::arbitrary(self)
172
149k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryNtNtCs4eJdYXiOSk9_10wasm_smith9component13CustomSectionEB1e_
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryINtNtCsbpSlAbJY2yh_5alloc3vec3VechEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
167
776
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
776
    where
169
776
        A: Arbitrary<'a>,
170
776
    {
171
776
        <A as Arbitrary<'a>>::arbitrary(self)
172
776
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryhECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
167
96.9k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
96.9k
    where
169
96.9k
        A: Arbitrary<'a>,
170
96.9k
    {
171
96.9k
        <A as Arbitrary<'a>>::arbitrary(self)
172
96.9k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryAhj10_ECs4eJdYXiOSk9_10wasm_smith
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryNtNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtB1i_6Module17arbitrary_valtype12ValTypeClassEB1k_
Line
Count
Source
167
16.2k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
16.2k
    where
169
16.2k
        A: Arbitrary<'a>,
170
16.2k
    {
171
16.2k
        <A as Arbitrary<'a>>::arbitrary(self)
172
16.2k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitrarylECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
167
3.45k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
3.45k
    where
169
3.45k
        A: Arbitrary<'a>,
170
3.45k
    {
171
3.45k
        <A as Arbitrary<'a>>::arbitrary(self)
172
3.45k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryxECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
167
1.43k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
1.43k
    where
169
1.43k
        A: Arbitrary<'a>,
170
1.43k
    {
171
1.43k
        <A as Arbitrary<'a>>::arbitrary(self)
172
1.43k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryfECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
167
1.67k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
1.67k
    where
169
1.67k
        A: Arbitrary<'a>,
170
1.67k
    {
171
1.67k
        <A as Arbitrary<'a>>::arbitrary(self)
172
1.67k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitrarydECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
167
1.06k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
1.06k
    where
169
1.06k
        A: Arbitrary<'a>,
170
1.06k
    {
171
1.06k
        <A as Arbitrary<'a>>::arbitrary(self)
172
1.06k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitrarynECs4eJdYXiOSk9_10wasm_smith
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitrarymECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
167
4.64k
    pub fn arbitrary<A>(&mut self) -> Result<A>
168
4.64k
    where
169
4.64k
        A: Arbitrary<'a>,
170
4.64k
    {
171
4.64k
        <A as Arbitrary<'a>>::arbitrary(self)
172
4.64k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitrarybEB5_
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryNtNtNtCs1ujR1JRCAmI_4core3net7ip_addr8Ipv6AddrEB5_
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured9arbitraryNtNtNtCs1ujR1JRCAmI_4core3net7ip_addr8Ipv4AddrEB5_
173
174
    /// Get the number of elements to insert when building up a collection of
175
    /// arbitrary `ElementType`s.
176
    ///
177
    /// This uses the [`<ElementType as
178
    /// Arbitrary>::size_hint`][crate::Arbitrary::size_hint] method to smartly
179
    /// choose a length such that we most likely have enough underlying bytes to
180
    /// construct that many arbitrary `ElementType`s.
181
    ///
182
    /// This should only be called within an `Arbitrary` implementation.
183
    ///
184
    /// # Example
185
    ///
186
    /// ```
187
    /// use arbitrary::{Arbitrary, Result, Unstructured};
188
    /// # pub struct MyCollection<T> { _t: std::marker::PhantomData<T> }
189
    /// # impl<T> MyCollection<T> {
190
    /// #     pub fn with_capacity(capacity: usize) -> Self { MyCollection { _t: std::marker::PhantomData } }
191
    /// #     pub fn insert(&mut self, element: T) {}
192
    /// # }
193
    ///
194
    /// impl<'a, T> Arbitrary<'a> for MyCollection<T>
195
    /// where
196
    ///     T: Arbitrary<'a>,
197
    /// {
198
    ///     fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
199
    ///         // Get the number of `T`s we should insert into our collection.
200
    ///         let len = u.arbitrary_len::<T>()?;
201
    ///
202
    ///         // And then create a collection of that length!
203
    ///         let mut my_collection = MyCollection::with_capacity(len);
204
    ///         for _ in 0..len {
205
    ///             let element = T::arbitrary(u)?;
206
    ///             my_collection.insert(element);
207
    ///         }
208
    ///
209
    ///         Ok(my_collection)
210
    ///     }
211
    /// }
212
    /// ```
213
14.1k
    pub fn arbitrary_len<ElementType>(&mut self) -> Result<usize>
214
14.1k
    where
215
14.1k
        ElementType: Arbitrary<'a>,
216
14.1k
    {
217
14.1k
        let byte_size = self.arbitrary_byte_size()?;
218
14.1k
        let (lower, upper) = <ElementType as Arbitrary>::size_hint(0);
219
14.1k
        let elem_size = upper.unwrap_or(lower * 2);
220
14.1k
        let elem_size = std::cmp::max(1, elem_size);
221
14.1k
        Ok(byte_size / elem_size)
222
14.1k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured13arbitrary_lenhECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
213
14.1k
    pub fn arbitrary_len<ElementType>(&mut self) -> Result<usize>
214
14.1k
    where
215
14.1k
        ElementType: Arbitrary<'a>,
216
14.1k
    {
217
14.1k
        let byte_size = self.arbitrary_byte_size()?;
218
14.1k
        let (lower, upper) = <ElementType as Arbitrary>::size_hint(0);
219
14.1k
        let elem_size = upper.unwrap_or(lower * 2);
220
14.1k
        let elem_size = std::cmp::max(1, elem_size);
221
14.1k
        Ok(byte_size / elem_size)
222
14.1k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured13arbitrary_lenhEB5_
223
224
14.1k
    fn arbitrary_byte_size(&mut self) -> Result<usize> {
225
14.1k
        if self.data.is_empty() {
226
938
            Ok(0)
227
13.1k
        } else if self.data.len() == 1 {
228
190
            self.data = &[];
229
190
            Ok(0)
230
        } else {
231
            // Take lengths from the end of the data, since the `libFuzzer` folks
232
            // found that this lets fuzzers more efficiently explore the input
233
            // space.
234
            //
235
            // https://github.com/rust-fuzz/libfuzzer-sys/blob/0c450753/libfuzzer/utils/FuzzedDataProvider.h#L92-L97
236
237
            // We only consume as many bytes as necessary to cover the entire
238
            // range of the byte string.
239
            // Note: We cast to u64 so we don't overflow when checking std::u32::MAX + 4 on 32-bit archs
240
12.9k
            let len = if self.data.len() as u64 <= std::u8::MAX as u64 + 1 {
241
11.8k
                let bytes = 1;
242
11.8k
                let max_size = self.data.len() - bytes;
243
11.8k
                let (rest, for_size) = self.data.split_at(max_size);
244
11.8k
                self.data = rest;
245
11.8k
                Self::int_in_range_impl(0..=max_size as u8, for_size.iter().copied())?.0 as usize
246
1.09k
            } else if self.data.len() as u64 <= std::u16::MAX as u64 + 2 {
247
1.09k
                let bytes = 2;
248
1.09k
                let max_size = self.data.len() - bytes;
249
1.09k
                let (rest, for_size) = self.data.split_at(max_size);
250
1.09k
                self.data = rest;
251
1.09k
                Self::int_in_range_impl(0..=max_size as u16, for_size.iter().copied())?.0 as usize
252
0
            } else if self.data.len() as u64 <= std::u32::MAX as u64 + 4 {
253
0
                let bytes = 4;
254
0
                let max_size = self.data.len() - bytes;
255
0
                let (rest, for_size) = self.data.split_at(max_size);
256
0
                self.data = rest;
257
0
                Self::int_in_range_impl(0..=max_size as u32, for_size.iter().copied())?.0 as usize
258
            } else {
259
0
                let bytes = 8;
260
0
                let max_size = self.data.len() - bytes;
261
0
                let (rest, for_size) = self.data.split_at(max_size);
262
0
                self.data = rest;
263
0
                Self::int_in_range_impl(0..=max_size as u64, for_size.iter().copied())?.0 as usize
264
            };
265
266
12.9k
            Ok(len)
267
        }
268
14.1k
    }
269
270
    /// Generate an integer within the given range.
271
    ///
272
    /// Do not use this to generate the size of a collection. Use
273
    /// `arbitrary_len` instead.
274
    ///
275
    /// # Panics
276
    ///
277
    /// Panics if `range.start > range.end`. That is, the given range must be
278
    /// non-empty.
279
    ///
280
    /// # Example
281
    ///
282
    /// ```
283
    /// use arbitrary::{Arbitrary, Unstructured};
284
    ///
285
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
286
    ///
287
    /// let x: i32 = u.int_in_range(-5_000..=-1_000)
288
    ///     .expect("constructed `u` with enough bytes to generate an `i32`");
289
    ///
290
    /// assert!(-5_000 <= x);
291
    /// assert!(x <= -1_000);
292
    /// ```
293
186k
    pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
294
186k
    where
295
186k
        T: Int,
296
186k
    {
297
186k
        let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
298
186k
        self.data = &self.data[bytes_consumed..];
299
186k
        Ok(result)
300
186k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangehECs4eJdYXiOSk9_10wasm_smith
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangejECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
293
33.9k
    pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
294
33.9k
    where
295
33.9k
        T: Int,
296
33.9k
    {
297
33.9k
        let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
298
33.9k
        self.data = &self.data[bytes_consumed..];
299
33.9k
        Ok(result)
300
33.9k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangelECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
293
5.31k
    pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
294
5.31k
    where
295
5.31k
        T: Int,
296
5.31k
    {
297
5.31k
        let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
298
5.31k
        self.data = &self.data[bytes_consumed..];
299
5.31k
        Ok(result)
300
5.31k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangemECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
293
84.9k
    pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
294
84.9k
    where
295
84.9k
        T: Int,
296
84.9k
    {
297
84.9k
        let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
298
84.9k
        self.data = &self.data[bytes_consumed..];
299
84.9k
        Ok(result)
300
84.9k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangetECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
293
9.80k
    pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
294
9.80k
    where
295
9.80k
        T: Int,
296
9.80k
    {
297
9.80k
        let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
298
9.80k
        self.data = &self.data[bytes_consumed..];
299
9.80k
        Ok(result)
300
9.80k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangeyECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
293
5.05k
    pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
294
5.05k
    where
295
5.05k
        T: Int,
296
5.05k
    {
297
5.05k
        let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
298
5.05k
        self.data = &self.data[bytes_consumed..];
299
5.05k
        Ok(result)
300
5.05k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangejEB5_
Line
Count
Source
293
47.7k
    pub fn int_in_range<T>(&mut self, range: ops::RangeInclusive<T>) -> Result<T>
294
47.7k
    where
295
47.7k
        T: Int,
296
47.7k
    {
297
47.7k
        let (result, bytes_consumed) = Self::int_in_range_impl(range, self.data.iter().cloned())?;
298
47.7k
        self.data = &self.data[bytes_consumed..];
299
47.7k
        Ok(result)
300
47.7k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured12int_in_rangemEB5_
301
302
199k
    fn int_in_range_impl<T>(
303
199k
        range: ops::RangeInclusive<T>,
304
199k
        mut bytes: impl Iterator<Item = u8>,
305
199k
    ) -> Result<(T, usize)>
306
199k
    where
307
199k
        T: Int,
308
199k
    {
309
199k
        let start = *range.start();
310
199k
        let end = *range.end();
311
199k
        assert!(
312
199k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
199k
        if start == end {
319
52.0k
            return Ok((start, 0));
320
147k
        }
321
147k
322
147k
        // From here on out we work with the unsigned representation. All of the
323
147k
        // operations performed below work out just as well whether or not `T`
324
147k
        // is a signed or unsigned integer.
325
147k
        let start = start.to_unsigned();
326
147k
        let end = end.to_unsigned();
327
147k
328
147k
        let delta = end.wrapping_sub(start);
329
147k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
147k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
147k
        let mut bytes_consumed: usize = 0;
337
338
375k
        while (bytes_consumed < mem::size_of::<T>())
339
360k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
240k
            let byte = match bytes.next() {
342
12.4k
                None => break,
343
228k
                Some(b) => b,
344
228k
            };
345
228k
            bytes_consumed += 1;
346
228k
347
228k
            // Combine this byte into our arbitrary integer, but avoid
348
228k
            // overflowing the shift for `u8` and `i8`.
349
228k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
11.8k
                T::Unsigned::from_u8(byte)
351
            } else {
352
216k
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
147k
        let offset = if delta == T::Unsigned::MAX {
357
11
            arbitrary_int
358
        } else {
359
147k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
147k
        let result = start.wrapping_add(offset);
365
147k
366
147k
        // And convert back to our maybe-signed representation.
367
147k
        let result = T::from_unsigned(result);
368
147k
        debug_assert!(*range.start() <= result);
369
147k
        debug_assert!(result <= *range.end());
370
371
147k
        Ok((result, bytes_consumed))
372
199k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implhINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_impljINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
302
33.9k
    fn int_in_range_impl<T>(
303
33.9k
        range: ops::RangeInclusive<T>,
304
33.9k
        mut bytes: impl Iterator<Item = u8>,
305
33.9k
    ) -> Result<(T, usize)>
306
33.9k
    where
307
33.9k
        T: Int,
308
33.9k
    {
309
33.9k
        let start = *range.start();
310
33.9k
        let end = *range.end();
311
33.9k
        assert!(
312
33.9k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
33.9k
        if start == end {
319
24.6k
            return Ok((start, 0));
320
9.29k
        }
321
9.29k
322
9.29k
        // From here on out we work with the unsigned representation. All of the
323
9.29k
        // operations performed below work out just as well whether or not `T`
324
9.29k
        // is a signed or unsigned integer.
325
9.29k
        let start = start.to_unsigned();
326
9.29k
        let end = end.to_unsigned();
327
9.29k
328
9.29k
        let delta = end.wrapping_sub(start);
329
9.29k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
9.29k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
9.29k
        let mut bytes_consumed: usize = 0;
337
338
18.1k
        while (bytes_consumed < mem::size_of::<T>())
339
18.1k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
9.29k
            let byte = match bytes.next() {
342
459
                None => break,
343
8.83k
                Some(b) => b,
344
8.83k
            };
345
8.83k
            bytes_consumed += 1;
346
8.83k
347
8.83k
            // Combine this byte into our arbitrary integer, but avoid
348
8.83k
            // overflowing the shift for `u8` and `i8`.
349
8.83k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
0
                T::Unsigned::from_u8(byte)
351
            } else {
352
8.83k
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
9.29k
        let offset = if delta == T::Unsigned::MAX {
357
0
            arbitrary_int
358
        } else {
359
9.29k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
9.29k
        let result = start.wrapping_add(offset);
365
9.29k
366
9.29k
        // And convert back to our maybe-signed representation.
367
9.29k
        let result = T::from_unsigned(result);
368
9.29k
        debug_assert!(*range.start() <= result);
369
9.29k
        debug_assert!(result <= *range.end());
370
371
9.29k
        Ok((result, bytes_consumed))
372
33.9k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_impllINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
302
5.31k
    fn int_in_range_impl<T>(
303
5.31k
        range: ops::RangeInclusive<T>,
304
5.31k
        mut bytes: impl Iterator<Item = u8>,
305
5.31k
    ) -> Result<(T, usize)>
306
5.31k
    where
307
5.31k
        T: Int,
308
5.31k
    {
309
5.31k
        let start = *range.start();
310
5.31k
        let end = *range.end();
311
5.31k
        assert!(
312
5.31k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
5.31k
        if start == end {
319
0
            return Ok((start, 0));
320
5.31k
        }
321
5.31k
322
5.31k
        // From here on out we work with the unsigned representation. All of the
323
5.31k
        // operations performed below work out just as well whether or not `T`
324
5.31k
        // is a signed or unsigned integer.
325
5.31k
        let start = start.to_unsigned();
326
5.31k
        let end = end.to_unsigned();
327
5.31k
328
5.31k
        let delta = end.wrapping_sub(start);
329
5.31k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
5.31k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
5.31k
        let mut bytes_consumed: usize = 0;
337
338
9.05k
        while (bytes_consumed < mem::size_of::<T>())
339
9.05k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
5.31k
            let byte = match bytes.next() {
342
1.56k
                None => break,
343
3.74k
                Some(b) => b,
344
3.74k
            };
345
3.74k
            bytes_consumed += 1;
346
3.74k
347
3.74k
            // Combine this byte into our arbitrary integer, but avoid
348
3.74k
            // overflowing the shift for `u8` and `i8`.
349
3.74k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
0
                T::Unsigned::from_u8(byte)
351
            } else {
352
3.74k
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
5.31k
        let offset = if delta == T::Unsigned::MAX {
357
0
            arbitrary_int
358
        } else {
359
5.31k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
5.31k
        let result = start.wrapping_add(offset);
365
5.31k
366
5.31k
        // And convert back to our maybe-signed representation.
367
5.31k
        let result = T::from_unsigned(result);
368
5.31k
        debug_assert!(*range.start() <= result);
369
5.31k
        debug_assert!(result <= *range.end());
370
371
5.31k
        Ok((result, bytes_consumed))
372
5.31k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implmINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
302
84.9k
    fn int_in_range_impl<T>(
303
84.9k
        range: ops::RangeInclusive<T>,
304
84.9k
        mut bytes: impl Iterator<Item = u8>,
305
84.9k
    ) -> Result<(T, usize)>
306
84.9k
    where
307
84.9k
        T: Int,
308
84.9k
    {
309
84.9k
        let start = *range.start();
310
84.9k
        let end = *range.end();
311
84.9k
        assert!(
312
84.9k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
84.9k
        if start == end {
319
0
            return Ok((start, 0));
320
84.9k
        }
321
84.9k
322
84.9k
        // From here on out we work with the unsigned representation. All of the
323
84.9k
        // operations performed below work out just as well whether or not `T`
324
84.9k
        // is a signed or unsigned integer.
325
84.9k
        let start = start.to_unsigned();
326
84.9k
        let end = end.to_unsigned();
327
84.9k
328
84.9k
        let delta = end.wrapping_sub(start);
329
84.9k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
84.9k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
84.9k
        let mut bytes_consumed: usize = 0;
337
338
250k
        while (bytes_consumed < mem::size_of::<T>())
339
250k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
167k
            let byte = match bytes.next() {
342
1.45k
                None => break,
343
166k
                Some(b) => b,
344
166k
            };
345
166k
            bytes_consumed += 1;
346
166k
347
166k
            // Combine this byte into our arbitrary integer, but avoid
348
166k
            // overflowing the shift for `u8` and `i8`.
349
166k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
0
                T::Unsigned::from_u8(byte)
351
            } else {
352
166k
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
84.9k
        let offset = if delta == T::Unsigned::MAX {
357
0
            arbitrary_int
358
        } else {
359
84.9k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
84.9k
        let result = start.wrapping_add(offset);
365
84.9k
366
84.9k
        // And convert back to our maybe-signed representation.
367
84.9k
        let result = T::from_unsigned(result);
368
84.9k
        debug_assert!(*range.start() <= result);
369
84.9k
        debug_assert!(result <= *range.end());
370
371
84.9k
        Ok((result, bytes_consumed))
372
84.9k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_impltINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
302
9.80k
    fn int_in_range_impl<T>(
303
9.80k
        range: ops::RangeInclusive<T>,
304
9.80k
        mut bytes: impl Iterator<Item = u8>,
305
9.80k
    ) -> Result<(T, usize)>
306
9.80k
    where
307
9.80k
        T: Int,
308
9.80k
    {
309
9.80k
        let start = *range.start();
310
9.80k
        let end = *range.end();
311
9.80k
        assert!(
312
9.80k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
9.80k
        if start == end {
319
0
            return Ok((start, 0));
320
9.80k
        }
321
9.80k
322
9.80k
        // From here on out we work with the unsigned representation. All of the
323
9.80k
        // operations performed below work out just as well whether or not `T`
324
9.80k
        // is a signed or unsigned integer.
325
9.80k
        let start = start.to_unsigned();
326
9.80k
        let end = end.to_unsigned();
327
9.80k
328
9.80k
        let delta = end.wrapping_sub(start);
329
9.80k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
9.80k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
9.80k
        let mut bytes_consumed: usize = 0;
337
338
13.3k
        while (bytes_consumed < mem::size_of::<T>())
339
11.6k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
11.6k
            let byte = match bytes.next() {
342
8.05k
                None => break,
343
3.57k
                Some(b) => b,
344
3.57k
            };
345
3.57k
            bytes_consumed += 1;
346
3.57k
347
3.57k
            // Combine this byte into our arbitrary integer, but avoid
348
3.57k
            // overflowing the shift for `u8` and `i8`.
349
3.57k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
0
                T::Unsigned::from_u8(byte)
351
            } else {
352
3.57k
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
9.80k
        let offset = if delta == T::Unsigned::MAX {
357
0
            arbitrary_int
358
        } else {
359
9.80k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
9.80k
        let result = start.wrapping_add(offset);
365
9.80k
366
9.80k
        // And convert back to our maybe-signed representation.
367
9.80k
        let result = T::from_unsigned(result);
368
9.80k
        debug_assert!(*range.start() <= result);
369
9.80k
        debug_assert!(result <= *range.end());
370
371
9.80k
        Ok((result, bytes_consumed))
372
9.80k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implyINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
302
5.05k
    fn int_in_range_impl<T>(
303
5.05k
        range: ops::RangeInclusive<T>,
304
5.05k
        mut bytes: impl Iterator<Item = u8>,
305
5.05k
    ) -> Result<(T, usize)>
306
5.05k
    where
307
5.05k
        T: Int,
308
5.05k
    {
309
5.05k
        let start = *range.start();
310
5.05k
        let end = *range.end();
311
5.05k
        assert!(
312
5.05k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
5.05k
        if start == end {
319
2.89k
            return Ok((start, 0));
320
2.16k
        }
321
2.16k
322
2.16k
        // From here on out we work with the unsigned representation. All of the
323
2.16k
        // operations performed below work out just as well whether or not `T`
324
2.16k
        // is a signed or unsigned integer.
325
2.16k
        let start = start.to_unsigned();
326
2.16k
        let end = end.to_unsigned();
327
2.16k
328
2.16k
        let delta = end.wrapping_sub(start);
329
2.16k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
2.16k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
2.16k
        let mut bytes_consumed: usize = 0;
337
338
8.53k
        while (bytes_consumed < mem::size_of::<T>())
339
8.53k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
6.53k
            let byte = match bytes.next() {
342
161
                None => break,
343
6.37k
                Some(b) => b,
344
6.37k
            };
345
6.37k
            bytes_consumed += 1;
346
6.37k
347
6.37k
            // Combine this byte into our arbitrary integer, but avoid
348
6.37k
            // overflowing the shift for `u8` and `i8`.
349
6.37k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
0
                T::Unsigned::from_u8(byte)
351
            } else {
352
6.37k
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
2.16k
        let offset = if delta == T::Unsigned::MAX {
357
0
            arbitrary_int
358
        } else {
359
2.16k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
2.16k
        let result = start.wrapping_add(offset);
365
2.16k
366
2.16k
        // And convert back to our maybe-signed representation.
367
2.16k
        let result = T::from_unsigned(result);
368
2.16k
        debug_assert!(*range.start() <= result);
369
2.16k
        debug_assert!(result <= *range.end());
370
371
2.16k
        Ok((result, bytes_consumed))
372
5.05k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implhINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1t_5slice4iter4IterhEEEB5_
Line
Count
Source
302
11.8k
    fn int_in_range_impl<T>(
303
11.8k
        range: ops::RangeInclusive<T>,
304
11.8k
        mut bytes: impl Iterator<Item = u8>,
305
11.8k
    ) -> Result<(T, usize)>
306
11.8k
    where
307
11.8k
        T: Int,
308
11.8k
    {
309
11.8k
        let start = *range.start();
310
11.8k
        let end = *range.end();
311
11.8k
        assert!(
312
11.8k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
11.8k
        if start == end {
319
0
            return Ok((start, 0));
320
11.8k
        }
321
11.8k
322
11.8k
        // From here on out we work with the unsigned representation. All of the
323
11.8k
        // operations performed below work out just as well whether or not `T`
324
11.8k
        // is a signed or unsigned integer.
325
11.8k
        let start = start.to_unsigned();
326
11.8k
        let end = end.to_unsigned();
327
11.8k
328
11.8k
        let delta = end.wrapping_sub(start);
329
11.8k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
11.8k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
11.8k
        let mut bytes_consumed: usize = 0;
337
338
23.7k
        while (bytes_consumed < mem::size_of::<T>())
339
11.8k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
11.8k
            let byte = match bytes.next() {
342
0
                None => break,
343
11.8k
                Some(b) => b,
344
11.8k
            };
345
11.8k
            bytes_consumed += 1;
346
11.8k
347
11.8k
            // Combine this byte into our arbitrary integer, but avoid
348
11.8k
            // overflowing the shift for `u8` and `i8`.
349
11.8k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
11.8k
                T::Unsigned::from_u8(byte)
351
            } else {
352
0
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
11.8k
        let offset = if delta == T::Unsigned::MAX {
357
11
            arbitrary_int
358
        } else {
359
11.8k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
11.8k
        let result = start.wrapping_add(offset);
365
11.8k
366
11.8k
        // And convert back to our maybe-signed representation.
367
11.8k
        let result = T::from_unsigned(result);
368
11.8k
        debug_assert!(*range.start() <= result);
369
11.8k
        debug_assert!(result <= *range.end());
370
371
11.8k
        Ok((result, bytes_consumed))
372
11.8k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_impljINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEEB5_
Line
Count
Source
302
47.7k
    fn int_in_range_impl<T>(
303
47.7k
        range: ops::RangeInclusive<T>,
304
47.7k
        mut bytes: impl Iterator<Item = u8>,
305
47.7k
    ) -> Result<(T, usize)>
306
47.7k
    where
307
47.7k
        T: Int,
308
47.7k
    {
309
47.7k
        let start = *range.start();
310
47.7k
        let end = *range.end();
311
47.7k
        assert!(
312
47.7k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
47.7k
        if start == end {
319
24.5k
            return Ok((start, 0));
320
23.2k
        }
321
23.2k
322
23.2k
        // From here on out we work with the unsigned representation. All of the
323
23.2k
        // operations performed below work out just as well whether or not `T`
324
23.2k
        // is a signed or unsigned integer.
325
23.2k
        let start = start.to_unsigned();
326
23.2k
        let end = end.to_unsigned();
327
23.2k
328
23.2k
        let delta = end.wrapping_sub(start);
329
23.2k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
23.2k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
23.2k
        let mut bytes_consumed: usize = 0;
337
338
48.6k
        while (bytes_consumed < mem::size_of::<T>())
339
48.6k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
26.1k
            let byte = match bytes.next() {
342
735
                None => break,
343
25.3k
                Some(b) => b,
344
25.3k
            };
345
25.3k
            bytes_consumed += 1;
346
25.3k
347
25.3k
            // Combine this byte into our arbitrary integer, but avoid
348
25.3k
            // overflowing the shift for `u8` and `i8`.
349
25.3k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
0
                T::Unsigned::from_u8(byte)
351
            } else {
352
25.3k
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
23.2k
        let offset = if delta == T::Unsigned::MAX {
357
0
            arbitrary_int
358
        } else {
359
23.2k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
23.2k
        let result = start.wrapping_add(offset);
365
23.2k
366
23.2k
        // And convert back to our maybe-signed representation.
367
23.2k
        let result = T::from_unsigned(result);
368
23.2k
        debug_assert!(*range.start() <= result);
369
23.2k
        debug_assert!(result <= *range.end());
370
371
23.2k
        Ok((result, bytes_consumed))
372
47.7k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implmINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1t_5slice4iter4IterhEEEB5_
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implmINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1t_5slice4iter4IterhEEEB5_
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_impltINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1t_5slice4iter4IterhEEEB5_
Line
Count
Source
302
1.09k
    fn int_in_range_impl<T>(
303
1.09k
        range: ops::RangeInclusive<T>,
304
1.09k
        mut bytes: impl Iterator<Item = u8>,
305
1.09k
    ) -> Result<(T, usize)>
306
1.09k
    where
307
1.09k
        T: Int,
308
1.09k
    {
309
1.09k
        let start = *range.start();
310
1.09k
        let end = *range.end();
311
1.09k
        assert!(
312
1.09k
            start <= end,
313
0
            "`arbitrary::Unstructured::int_in_range` requires a non-empty range"
314
        );
315
316
        // When there is only one possible choice, don't waste any entropy from
317
        // the underlying data.
318
1.09k
        if start == end {
319
0
            return Ok((start, 0));
320
1.09k
        }
321
1.09k
322
1.09k
        // From here on out we work with the unsigned representation. All of the
323
1.09k
        // operations performed below work out just as well whether or not `T`
324
1.09k
        // is a signed or unsigned integer.
325
1.09k
        let start = start.to_unsigned();
326
1.09k
        let end = end.to_unsigned();
327
1.09k
328
1.09k
        let delta = end.wrapping_sub(start);
329
1.09k
        debug_assert_ne!(delta, T::Unsigned::ZERO);
330
331
        // Compute an arbitrary integer offset from the start of the range. We
332
        // do this by consuming `size_of(T)` bytes from the input to create an
333
        // arbitrary integer and then clamping that int into our range bounds
334
        // with a modulo operation.
335
1.09k
        let mut arbitrary_int = T::Unsigned::ZERO;
336
1.09k
        let mut bytes_consumed: usize = 0;
337
338
3.27k
        while (bytes_consumed < mem::size_of::<T>())
339
2.19k
            && (delta >> T::Unsigned::from_usize(bytes_consumed * 8)) > T::Unsigned::ZERO
340
        {
341
2.17k
            let byte = match bytes.next() {
342
0
                None => break,
343
2.17k
                Some(b) => b,
344
2.17k
            };
345
2.17k
            bytes_consumed += 1;
346
2.17k
347
2.17k
            // Combine this byte into our arbitrary integer, but avoid
348
2.17k
            // overflowing the shift for `u8` and `i8`.
349
2.17k
            arbitrary_int = if mem::size_of::<T>() == 1 {
350
0
                T::Unsigned::from_u8(byte)
351
            } else {
352
2.17k
                (arbitrary_int << 8) | T::Unsigned::from_u8(byte)
353
            };
354
        }
355
356
1.09k
        let offset = if delta == T::Unsigned::MAX {
357
0
            arbitrary_int
358
        } else {
359
1.09k
            arbitrary_int % (delta.checked_add(T::Unsigned::ONE).unwrap())
360
        };
361
362
        // Finally, we add `start` to our offset from `start` to get the result
363
        // actual value within the range.
364
1.09k
        let result = start.wrapping_add(offset);
365
1.09k
366
1.09k
        // And convert back to our maybe-signed representation.
367
1.09k
        let result = T::from_unsigned(result);
368
1.09k
        debug_assert!(*range.start() <= result);
369
1.09k
        debug_assert!(result <= *range.end());
370
371
1.09k
        Ok((result, bytes_consumed))
372
1.09k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured17int_in_range_implyINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1t_5slice4iter4IterhEEEB5_
373
374
    /// Choose one of the given choices.
375
    ///
376
    /// This should only be used inside of `Arbitrary` implementations.
377
    ///
378
    /// Returns an error if there is not enough underlying data to make a
379
    /// choice or if no choices are provided.
380
    ///
381
    /// # Examples
382
    ///
383
    /// Selecting from an array of choices:
384
    ///
385
    /// ```
386
    /// use arbitrary::Unstructured;
387
    ///
388
    /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
389
    /// let choices = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
390
    ///
391
    /// let choice = u.choose(&choices).unwrap();
392
    ///
393
    /// println!("chose {}", choice);
394
    /// ```
395
    ///
396
    /// An error is returned if no choices are provided:
397
    ///
398
    /// ```
399
    /// use arbitrary::Unstructured;
400
    ///
401
    /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
402
    /// let choices: [char; 0] = [];
403
    ///
404
    /// let result = u.choose(&choices);
405
    ///
406
    /// assert!(result.is_err());
407
    /// ```
408
47.7k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
47.7k
        let idx = self.choose_index(choices.len())?;
410
47.7k
        Ok(&choices[idx])
411
47.7k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseFG1_QL2_IBH_L1_EQL0_NtNtCs4eJdYXiOSk9_10wasm_smith4core6ModuleEINtNtCs1ujR1JRCAmI_4core6result6ResultNtB1t_10EntityTypeNtNtB5_5error5ErrorEEB1v_
Line
Count
Source
408
4.32k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
4.32k
        let idx = self.choose_index(choices.len())?;
410
4.32k
        Ok(&choices[idx])
411
4.32k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseFG1_QL2_IBH_L1_EQL0_NtNtCs4eJdYXiOSk9_10wasm_smith9component16ComponentBuilderEINtNtCs1ujR1JRCAmI_4core6result6ResultINtNtB2t_6option6OptionNtB1t_4FuncENtNtB5_5error5ErrorEEB1v_
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseFG1_QL2_NtNtCs4eJdYXiOSk9_10wasm_smith9component16ComponentBuilderQL1_IBH_L0_EEINtNtCs1ujR1JRCAmI_4core6result6ResultNtB1h_4StepNtNtB5_5error5ErrorEEB1j_
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseFG1_RL2_NtNtCs4eJdYXiOSk9_10wasm_smith9component16ComponentBuilderQL1_IBH_L0_EEINtNtCs1ujR1JRCAmI_4core6result6ResultNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component7imports16ComponentTypeRefNtNtB5_5error5ErrorEEB1j_
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseFG3_RL4_NtNtCs4eJdYXiOSk9_10wasm_smith9component16ComponentBuilderQL3_IBH_L2_EQL1_NtB1h_12EntityCountsRL0_SINtNtCsbpSlAbJY2yh_5alloc2rc2RcNtNtB1j_4core8FuncTypeEEINtNtCs1ujR1JRCAmI_4core6result6ResultNtB3n_10EntityTypeNtNtB5_5error5ErrorEEB1j_
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseFG4_QL5_NtNtCs4eJdYXiOSk9_10wasm_smith9component16ComponentBuilderQL4_INtNtNtNtCs5s0IcynIBo_3std11collections4hash3set7HashSetNtNtCsbpSlAbJY2yh_5alloc6string6StringEQL3_B2f_QL2_IBH_L1_EQL0_mEINtNtCs1ujR1JRCAmI_4core6result6ResultNtB1h_16InstanceTypeDeclNtNtB5_5error5ErrorEEB1j_
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseINtNtCsbpSlAbJY2yh_5alloc3vec3VecTNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core7exports10ExportKindmEEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
408
5.20k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
5.20k
        let idx = self.choose_index(choices.len())?;
410
5.20k
        Ok(&choices[idx])
411
5.20k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDG0_INtNtNtCs1ujR1JRCAmI_4core3ops8function2FnTQL1_IBH_L0_EEEp6OutputINtNtB1R_6result6ResultNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4code9BlockTypeNtNtB5_5error5ErrorEEL_EECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
408
6.68k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
6.68k
        let idx = self.choose_index(choices.len())?;
410
6.68k
        Ok(&choices[idx])
411
6.68k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDG0_INtNtNtCs1ujR1JRCAmI_4core3ops8function2FnTQL1_IBH_L0_EEEp6OutputINtNtB1R_6result6ResultTNtNtCs4eJdYXiOSk9_10wasm_smith4core11ElementKindINtNtB1R_6option6OptionyEENtNtB5_5error5ErrorEEL_EEB3f_
Line
Count
Source
408
1.58k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
1.58k
        let idx = self.choose_index(choices.len())?;
410
1.58k
        Ok(&choices[idx])
411
1.58k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDG0_INtNtNtCs1ujR1JRCAmI_4core3ops8function2FnTQL1_IBH_L0_ENtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core5types7ValTypeEEp6OutputINtNtB1R_6result6ResultNtNtB2H_4code9ConstExprNtNtB5_5error5ErrorEEL_EECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
408
2.50k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
2.50k
        let idx = self.choose_index(choices.len())?;
410
2.50k
        Ok(&choices[idx])
411
2.50k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDG0_INtNtNtCs1ujR1JRCAmI_4core3ops8function2FnTQL1_IBH_L0_EyjEEp6OutputINtNtB1R_6result6ResultNtNtCs4eJdYXiOSk9_10wasm_smith4core6OffsetNtNtB5_5error5ErrorEEL_EEB3g_
Line
Count
Source
408
776
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
776
        let idx = self.choose_index(choices.len())?;
410
776
        Ok(&choices[idx])
411
776
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseINtNtCsbpSlAbJY2yh_5alloc5boxed3BoxDG2_INtNtNtCs1ujR1JRCAmI_4core3ops8function2FnTQL3_IBH_L2_EQL1_INtNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11CodeBuilderL0_EEEp6OutputINtNtB1R_6result6ResultNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4code5CatchNtNtB5_5error5ErrorEEL_EEB2O_
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseINtNtNtCs1ujR1JRCAmI_4core3ops5range5RangejEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core5types7RefTypeECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core5types7ValTypeECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core5types8HeapTypeECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component5types16ComponentValTypeECs4eJdYXiOSk9_10wasm_smith
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseTNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core7exports10ExportKindmEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
408
5.20k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
5.20k
        let idx = self.choose_index(choices.len())?;
410
5.20k
        Ok(&choices[idx])
411
5.20k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseTjRNtNtCs4eJdYXiOSk9_10wasm_smith9component10TypesScopeEEB1e_
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseTmRNtNtCs4eJdYXiOSk9_10wasm_smith4core8FuncTypeEEB1e_
Line
Count
Source
408
461
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
461
        let idx = self.choose_index(choices.len())?;
410
461
        Ok(&choices[idx])
411
461
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseTmmEECs4eJdYXiOSk9_10wasm_smith
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6choosemECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
408
18.0k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
18.0k
        let idx = self.choose_index(choices.len())?;
410
18.0k
        Ok(&choices[idx])
411
18.0k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6chooseyECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
408
2.93k
    pub fn choose<'b, T>(&mut self, choices: &'b [T]) -> Result<&'b T> {
409
2.93k
        let idx = self.choose_index(choices.len())?;
410
2.93k
        Ok(&choices[idx])
411
2.93k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured6choosepEB5_
412
413
    /// Choose a value in `0..len`.
414
    ///
415
    /// Returns an error if the `len` is zero.
416
    ///
417
    /// # Examples
418
    ///
419
    /// Using Fisher–Yates shuffle shuffle to gerate an arbitrary permutation.
420
    ///
421
    /// [Fisher–Yates shuffle]: https://en.wikipedia.org/wiki/Fisher–Yates_shuffle
422
    ///
423
    /// ```
424
    /// use arbitrary::Unstructured;
425
    ///
426
    /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
427
    /// let mut permutation = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
428
    /// let mut to_permute = &mut permutation[..];
429
    /// while to_permute.len() > 1 {
430
    ///     let idx = u.choose_index(to_permute.len()).unwrap();
431
    ///     to_permute.swap(0, idx);
432
    ///     to_permute = &mut to_permute[1..];
433
    /// }
434
    ///
435
    /// println!("permutation: {:?}", permutation);
436
    /// ```
437
    ///
438
    /// An error is returned if the length is zero:
439
    ///
440
    /// ```
441
    /// use arbitrary::Unstructured;
442
    ///
443
    /// let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
444
    /// let array: [i32; 0] = [];
445
    ///
446
    /// let result = u.choose_index(array.len());
447
    ///
448
    /// assert!(result.is_err());
449
    /// ```
450
47.7k
    pub fn choose_index(&mut self, len: usize) -> Result<usize> {
451
47.7k
        if len == 0 {
452
0
            return Err(Error::EmptyChoose);
453
47.7k
        }
454
47.7k
        let idx = self.int_in_range(0..=len - 1)?;
455
47.7k
        Ok(idx)
456
47.7k
    }
457
458
    /// Generate a boolean according to the given ratio.
459
    ///
460
    /// # Panics
461
    ///
462
    /// Panics when the numerator and denominator do not meet these constraints:
463
    ///
464
    /// * `0 < numerator <= denominator`
465
    ///
466
    /// # Example
467
    ///
468
    /// Generate a boolean that is `true` five sevenths of the time:
469
    ///
470
    /// ```
471
    /// # fn foo() -> arbitrary::Result<()> {
472
    /// use arbitrary::Unstructured;
473
    ///
474
    /// # let my_data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
475
    /// let mut u = Unstructured::new(&my_data);
476
    ///
477
    /// if u.ratio(5, 7)? {
478
    ///     // Take this branch 5/7 of the time.
479
    /// }
480
    /// # Ok(())
481
    /// # }
482
    /// ```
483
15.1k
    pub fn ratio<T>(&mut self, numerator: T, denominator: T) -> Result<bool>
484
15.1k
    where
485
15.1k
        T: Int,
486
15.1k
    {
487
15.1k
        assert!(T::ZERO < numerator);
488
15.1k
        assert!(numerator <= denominator);
489
15.1k
        let x = self.int_in_range(T::ONE..=denominator)?;
490
15.1k
        Ok(x <= numerator)
491
15.1k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured5ratiohECs4eJdYXiOSk9_10wasm_smith
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured5ratiolECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
483
5.31k
    pub fn ratio<T>(&mut self, numerator: T, denominator: T) -> Result<bool>
484
5.31k
    where
485
5.31k
        T: Int,
486
5.31k
    {
487
5.31k
        assert!(T::ZERO < numerator);
488
5.31k
        assert!(numerator <= denominator);
489
5.31k
        let x = self.int_in_range(T::ONE..=denominator)?;
490
5.31k
        Ok(x <= numerator)
491
5.31k
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured5ratiotECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
483
9.80k
    pub fn ratio<T>(&mut self, numerator: T, denominator: T) -> Result<bool>
484
9.80k
    where
485
9.80k
        T: Int,
486
9.80k
    {
487
9.80k
        assert!(T::ZERO < numerator);
488
9.80k
        assert!(numerator <= denominator);
489
9.80k
        let x = self.int_in_range(T::ONE..=denominator)?;
490
9.80k
        Ok(x <= numerator)
491
9.80k
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured5ratiopEB5_
492
493
    /// Fill a `buffer` with bytes from the underlying raw data.
494
    ///
495
    /// This should only be called within an `Arbitrary` implementation. This is
496
    /// a very low-level operation. You should generally prefer calling nested
497
    /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and
498
    /// `String::arbitrary` over using this method directly.
499
    ///
500
    /// If this `Unstructured` does not have enough underlying data to fill the
501
    /// whole `buffer`, it pads the buffer out with zeros.
502
    ///
503
    /// # Example
504
    ///
505
    /// ```
506
    /// use arbitrary::Unstructured;
507
    ///
508
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
509
    ///
510
    /// let mut buf = [0; 2];
511
    ///
512
    /// assert!(u.fill_buffer(&mut buf).is_ok());
513
    /// assert_eq!(buf, [1, 2]);
514
    ///
515
    /// assert!(u.fill_buffer(&mut buf).is_ok());
516
    /// assert_eq!(buf, [3, 4]);
517
    ///
518
    /// assert!(u.fill_buffer(&mut buf).is_ok());
519
    /// assert_eq!(buf, [0, 0]);
520
    /// ```
521
277k
    pub fn fill_buffer(&mut self, buffer: &mut [u8]) -> Result<()> {
522
277k
        let n = std::cmp::min(buffer.len(), self.data.len());
523
277k
        buffer[..n].copy_from_slice(&self.data[..n]);
524
277k
        for byte in buffer[n..].iter_mut() {
525
42.3k
            *byte = 0;
526
42.3k
        }
527
277k
        self.data = &self.data[n..];
528
277k
        Ok(())
529
277k
    }
530
531
    /// Provide `size` bytes from the underlying raw data.
532
    ///
533
    /// This should only be called within an `Arbitrary` implementation. This is
534
    /// a very low-level operation. You should generally prefer calling nested
535
    /// `Arbitrary` implementations like `<Vec<u8>>::arbitrary` and
536
    /// `String::arbitrary` over using this method directly.
537
    ///
538
    /// # Example
539
    ///
540
    /// ```
541
    /// use arbitrary::Unstructured;
542
    ///
543
    /// let mut u = Unstructured::new(&[1, 2, 3, 4]);
544
    ///
545
    /// assert!(u.bytes(2).unwrap() == &[1, 2]);
546
    /// assert!(u.bytes(2).unwrap() == &[3, 4]);
547
    /// ```
548
14.1k
    pub fn bytes(&mut self, size: usize) -> Result<&'a [u8]> {
549
14.1k
        if self.data.len() < size {
550
0
            return Err(Error::NotEnoughData);
551
14.1k
        }
552
14.1k
553
14.1k
        let (for_buf, rest) = self.data.split_at(size);
554
14.1k
        self.data = rest;
555
14.1k
        Ok(for_buf)
556
14.1k
    }
557
558
    /// Peek at `size` number of bytes of the underlying raw input.
559
    ///
560
    /// Does not consume the bytes, only peeks at them.
561
    ///
562
    /// Returns `None` if there are not `size` bytes left in the underlying raw
563
    /// input.
564
    ///
565
    /// # Example
566
    ///
567
    /// ```
568
    /// use arbitrary::Unstructured;
569
    ///
570
    /// let u = Unstructured::new(&[1, 2, 3]);
571
    ///
572
    /// assert_eq!(u.peek_bytes(0).unwrap(), []);
573
    /// assert_eq!(u.peek_bytes(1).unwrap(), [1]);
574
    /// assert_eq!(u.peek_bytes(2).unwrap(), [1, 2]);
575
    /// assert_eq!(u.peek_bytes(3).unwrap(), [1, 2, 3]);
576
    ///
577
    /// assert!(u.peek_bytes(4).is_none());
578
    /// ```
579
14.1k
    pub fn peek_bytes(&self, size: usize) -> Option<&'a [u8]> {
580
14.1k
        self.data.get(..size)
581
14.1k
    }
582
583
    /// Consume all of the rest of the remaining underlying bytes.
584
    ///
585
    /// Returns a slice of all the remaining, unconsumed bytes.
586
    ///
587
    /// # Example
588
    ///
589
    /// ```
590
    /// use arbitrary::Unstructured;
591
    ///
592
    /// let mut u = Unstructured::new(&[1, 2, 3]);
593
    ///
594
    /// let mut remaining = u.take_rest();
595
    ///
596
    /// assert_eq!(remaining, [1, 2, 3]);
597
    /// ```
598
0
    pub fn take_rest(mut self) -> &'a [u8] {
599
0
        mem::take(&mut self.data)
600
0
    }
601
602
    /// Provide an iterator over elements for constructing a collection
603
    ///
604
    /// This is useful for implementing [`Arbitrary::arbitrary`] on collections
605
    /// since the implementation is simply `u.arbitrary_iter()?.collect()`
606
776
    pub fn arbitrary_iter<'b, ElementType: Arbitrary<'a>>(
607
776
        &'b mut self,
608
776
    ) -> Result<ArbitraryIter<'a, 'b, ElementType>> {
609
776
        Ok(ArbitraryIter {
610
776
            u: &mut *self,
611
776
            _marker: PhantomData,
612
776
        })
613
776
    }
_RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured14arbitrary_iterhECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
606
776
    pub fn arbitrary_iter<'b, ElementType: Arbitrary<'a>>(
607
776
        &'b mut self,
608
776
    ) -> Result<ArbitraryIter<'a, 'b, ElementType>> {
609
776
        Ok(ArbitraryIter {
610
776
            u: &mut *self,
611
776
            _marker: PhantomData,
612
776
        })
613
776
    }
Unexecuted instantiation: _RINvMNtCsgsv2Y6Qu5CW_9arbitrary12unstructuredNtB3_12Unstructured14arbitrary_iterhEB5_
614
615
    /// Provide an iterator over elements for constructing a collection from
616
    /// all the remaining bytes.
617
    ///
618
    /// This is useful for implementing [`Arbitrary::arbitrary_take_rest`] on collections
619
    /// since the implementation is simply `u.arbitrary_take_rest_iter()?.collect()`
620
0
    pub fn arbitrary_take_rest_iter<ElementType: Arbitrary<'a>>(
621
0
        self,
622
0
    ) -> Result<ArbitraryTakeRestIter<'a, ElementType>> {
623
0
        Ok(ArbitraryTakeRestIter {
624
0
            u: self,
625
0
            _marker: PhantomData,
626
0
        })
627
0
    }
628
629
    /// Call the given function an arbitrary number of times.
630
    ///
631
    /// The function is given this `Unstructured` so that it can continue to
632
    /// generate arbitrary data and structures.
633
    ///
634
    /// You may optionaly specify minimum and maximum bounds on the number of
635
    /// times the function is called.
636
    ///
637
    /// You may break out of the loop early by returning
638
    /// `Ok(std::ops::ControlFlow::Break)`. To continue the loop, return
639
    /// `Ok(std::ops::ControlFlow::Continue)`.
640
    ///
641
    /// # Panics
642
    ///
643
    /// Panics if `min > max`.
644
    ///
645
    /// # Example
646
    ///
647
    /// Call a closure that generates an arbitrary type inside a context an
648
    /// arbitrary number of times:
649
    ///
650
    /// ```
651
    /// use arbitrary::{Result, Unstructured};
652
    /// use std::ops::ControlFlow;
653
    ///
654
    /// enum Type {
655
    ///     /// A boolean type.
656
    ///     Bool,
657
    ///
658
    ///     /// An integer type.
659
    ///     Int,
660
    ///
661
    ///     /// A list of the `i`th type in this type's context.
662
    ///     List(usize),
663
    /// }
664
    ///
665
    /// fn arbitrary_types_context(u: &mut Unstructured) -> Result<Vec<Type>> {
666
    ///     let mut context = vec![];
667
    ///
668
    ///     u.arbitrary_loop(Some(10), Some(20), |u| {
669
    ///         let num_choices = if context.is_empty() {
670
    ///             2
671
    ///         } else {
672
    ///             3
673
    ///         };
674
    ///         let ty = match u.int_in_range::<u8>(1..=num_choices)? {
675
    ///             1 => Type::Bool,
676
    ///             2 => Type::Int,
677
    ///             3 => Type::List(u.int_in_range(0..=context.len() - 1)?),
678
    ///             _ => unreachable!(),
679
    ///         };
680
    ///         context.push(ty);
681
    ///         Ok(ControlFlow::Continue(()))
682
    ///     })?;
683
    ///
684
    ///     // The number of loop iterations are constrained by the min/max
685
    ///     // bounds that we provided.
686
    ///     assert!(context.len() >= 10);
687
    ///     assert!(context.len() <= 20);
688
    ///
689
    ///     Ok(context)
690
    /// }
691
    /// ```
692
0
    pub fn arbitrary_loop(
693
0
        &mut self,
694
0
        min: Option<u32>,
695
0
        max: Option<u32>,
696
0
        mut f: impl FnMut(&mut Self) -> Result<ControlFlow<(), ()>>,
697
0
    ) -> Result<()> {
698
0
        let min = min.unwrap_or(0);
699
0
        let max = max.unwrap_or(u32::MAX);
700
0
701
0
        for _ in 0..self.int_in_range(min..=max)? {
702
0
            match f(self)? {
703
0
                ControlFlow::Continue(_) => continue,
704
0
                ControlFlow::Break(_) => break,
705
            }
706
        }
707
708
0
        Ok(())
709
0
    }
710
}
711
712
/// Utility iterator produced by [`Unstructured::arbitrary_iter`]
713
pub struct ArbitraryIter<'a, 'b, ElementType> {
714
    u: &'b mut Unstructured<'a>,
715
    _marker: PhantomData<ElementType>,
716
}
717
718
impl<'a, 'b, ElementType: Arbitrary<'a>> Iterator for ArbitraryIter<'a, 'b, ElementType> {
719
    type Item = Result<ElementType>;
720
3.49k
    fn next(&mut self) -> Option<Result<ElementType>> {
721
3.49k
        let keep_going = self.u.arbitrary().unwrap_or(false);
722
3.49k
        if keep_going {
723
2.71k
            Some(Arbitrary::arbitrary(self.u))
724
        } else {
725
776
            None
726
        }
727
3.49k
    }
_RNvXs_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredINtB4_13ArbitraryIterhENtNtNtNtCs1ujR1JRCAmI_4core4iter6traits8iterator8Iterator4nextCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
720
3.49k
    fn next(&mut self) -> Option<Result<ElementType>> {
721
3.49k
        let keep_going = self.u.arbitrary().unwrap_or(false);
722
3.49k
        if keep_going {
723
2.71k
            Some(Arbitrary::arbitrary(self.u))
724
        } else {
725
776
            None
726
        }
727
3.49k
    }
Unexecuted instantiation: _RNvXs_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredINtB4_13ArbitraryIterhENtNtNtNtCs1ujR1JRCAmI_4core4iter6traits8iterator8Iterator4nextB6_
728
}
729
730
/// Utility iterator produced by [`Unstructured::arbitrary_take_rest_iter`]
731
pub struct ArbitraryTakeRestIter<'a, ElementType> {
732
    u: Unstructured<'a>,
733
    _marker: PhantomData<ElementType>,
734
}
735
736
impl<'a, ElementType: Arbitrary<'a>> Iterator for ArbitraryTakeRestIter<'a, ElementType> {
737
    type Item = Result<ElementType>;
738
0
    fn next(&mut self) -> Option<Result<ElementType>> {
739
0
        let keep_going = self.u.arbitrary().unwrap_or(false);
740
0
        if keep_going {
741
0
            Some(Arbitrary::arbitrary(&mut self.u))
742
        } else {
743
0
            None
744
        }
745
0
    }
746
}
747
748
/// A trait that is implemented for all of the primitive integers:
749
///
750
/// * `u8`
751
/// * `u16`
752
/// * `u32`
753
/// * `u64`
754
/// * `u128`
755
/// * `usize`
756
/// * `i8`
757
/// * `i16`
758
/// * `i32`
759
/// * `i64`
760
/// * `i128`
761
/// * `isize`
762
///
763
/// Don't implement this trait yourself.
764
pub trait Int:
765
    Copy
766
    + std::fmt::Debug
767
    + PartialOrd
768
    + Ord
769
    + ops::Sub<Self, Output = Self>
770
    + ops::Rem<Self, Output = Self>
771
    + ops::Shr<Self, Output = Self>
772
    + ops::Shl<usize, Output = Self>
773
    + ops::BitOr<Self, Output = Self>
774
{
775
    #[doc(hidden)]
776
    type Unsigned: Int;
777
778
    #[doc(hidden)]
779
    const ZERO: Self;
780
781
    #[doc(hidden)]
782
    const ONE: Self;
783
784
    #[doc(hidden)]
785
    const MAX: Self;
786
787
    #[doc(hidden)]
788
    fn from_u8(b: u8) -> Self;
789
790
    #[doc(hidden)]
791
    fn from_usize(u: usize) -> Self;
792
793
    #[doc(hidden)]
794
    fn checked_add(self, rhs: Self) -> Option<Self>;
795
796
    #[doc(hidden)]
797
    fn wrapping_add(self, rhs: Self) -> Self;
798
799
    #[doc(hidden)]
800
    fn wrapping_sub(self, rhs: Self) -> Self;
801
802
    #[doc(hidden)]
803
    fn to_unsigned(self) -> Self::Unsigned;
804
805
    #[doc(hidden)]
806
    fn from_unsigned(unsigned: Self::Unsigned) -> Self;
807
}
808
809
macro_rules! impl_int {
810
    ( $( $ty:ty : $unsigned_ty: ty ; )* ) => {
811
        $(
812
            impl Int for $ty {
813
                type Unsigned = $unsigned_ty;
814
815
                const ZERO: Self = 0;
816
817
                const ONE: Self = 1;
818
819
                const MAX: Self = Self::MAX;
820
821
228k
                fn from_u8(b: u8) -> Self {
822
228k
                    b as Self
823
228k
                }
Unexecuted instantiation: _RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int7from_u8Cs4eJdYXiOSk9_10wasm_smith
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int7from_u8Cs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
821
3.57k
                fn from_u8(b: u8) -> Self {
822
3.57k
                    b as Self
823
3.57k
                }
_RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int7from_u8Cs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
821
169k
                fn from_u8(b: u8) -> Self {
822
169k
                    b as Self
823
169k
                }
_RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int7from_u8Cs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
821
6.37k
                fn from_u8(b: u8) -> Self {
822
6.37k
                    b as Self
823
6.37k
                }
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int7from_u8Cs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
821
8.83k
                fn from_u8(b: u8) -> Self {
822
8.83k
                    b as Self
823
8.83k
                }
_RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int7from_u8B7_
Line
Count
Source
821
11.8k
                fn from_u8(b: u8) -> Self {
822
11.8k
                    b as Self
823
11.8k
                }
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int7from_u8B7_
Line
Count
Source
821
2.17k
                fn from_u8(b: u8) -> Self {
822
2.17k
                    b as Self
823
2.17k
                }
Unexecuted instantiation: _RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs5_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredoNtB5_3Int7from_u8B7_
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int7from_u8B7_
Line
Count
Source
821
25.3k
                fn from_u8(b: u8) -> Self {
822
25.3k
                    b as Self
823
25.3k
                }
Unexecuted instantiation: _RNvXs7_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredaNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs8_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredsNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXsa_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredxNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXsb_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurednNtB5_3Int7from_u8B7_
Unexecuted instantiation: _RNvXsc_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurediNtB5_3Int7from_u8B7_
824
825
360k
                fn from_usize(u: usize) -> Self {
826
360k
                    u as Self
827
360k
                }
Unexecuted instantiation: _RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int10from_usizeCs4eJdYXiOSk9_10wasm_smith
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int10from_usizeCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
825
11.6k
                fn from_usize(u: usize) -> Self {
826
11.6k
                    u as Self
827
11.6k
                }
_RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int10from_usizeCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
825
259k
                fn from_usize(u: usize) -> Self {
826
259k
                    u as Self
827
259k
                }
_RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int10from_usizeCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
825
8.53k
                fn from_usize(u: usize) -> Self {
826
8.53k
                    u as Self
827
8.53k
                }
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int10from_usizeCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
825
18.1k
                fn from_usize(u: usize) -> Self {
826
18.1k
                    u as Self
827
18.1k
                }
_RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int10from_usizeB7_
Line
Count
Source
825
11.8k
                fn from_usize(u: usize) -> Self {
826
11.8k
                    u as Self
827
11.8k
                }
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int10from_usizeB7_
Line
Count
Source
825
2.19k
                fn from_usize(u: usize) -> Self {
826
2.19k
                    u as Self
827
2.19k
                }
Unexecuted instantiation: _RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs5_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredoNtB5_3Int10from_usizeB7_
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int10from_usizeB7_
Line
Count
Source
825
48.6k
                fn from_usize(u: usize) -> Self {
826
48.6k
                    u as Self
827
48.6k
                }
Unexecuted instantiation: _RNvXs7_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredaNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs8_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredsNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXsa_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredxNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXsb_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurednNtB5_3Int10from_usizeB7_
Unexecuted instantiation: _RNvXsc_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurediNtB5_3Int10from_usizeB7_
828
829
147k
                fn checked_add(self, rhs: Self) -> Option<Self> {
830
147k
                    <$ty>::checked_add(self, rhs)
831
147k
                }
_RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int11checked_add
Line
Count
Source
829
11.8k
                fn checked_add(self, rhs: Self) -> Option<Self> {
830
11.8k
                    <$ty>::checked_add(self, rhs)
831
11.8k
                }
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int11checked_add
Line
Count
Source
829
10.9k
                fn checked_add(self, rhs: Self) -> Option<Self> {
830
10.9k
                    <$ty>::checked_add(self, rhs)
831
10.9k
                }
_RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int11checked_add
Line
Count
Source
829
90.2k
                fn checked_add(self, rhs: Self) -> Option<Self> {
830
90.2k
                    <$ty>::checked_add(self, rhs)
831
90.2k
                }
_RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int11checked_add
Line
Count
Source
829
2.16k
                fn checked_add(self, rhs: Self) -> Option<Self> {
830
2.16k
                    <$ty>::checked_add(self, rhs)
831
2.16k
                }
Unexecuted instantiation: _RNvXs5_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredoNtB5_3Int11checked_add
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int11checked_add
Line
Count
Source
829
32.5k
                fn checked_add(self, rhs: Self) -> Option<Self> {
830
32.5k
                    <$ty>::checked_add(self, rhs)
831
32.5k
                }
Unexecuted instantiation: _RNvXs7_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredaNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs8_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredsNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXsa_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredxNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXsb_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurednNtB5_3Int11checked_add
Unexecuted instantiation: _RNvXsc_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurediNtB5_3Int11checked_add
832
833
147k
                fn wrapping_add(self, rhs: Self) -> Self {
834
147k
                    <$ty>::wrapping_add(self, rhs)
835
147k
                }
Unexecuted instantiation: _RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int12wrapping_addCs4eJdYXiOSk9_10wasm_smith
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int12wrapping_addCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
833
9.80k
                fn wrapping_add(self, rhs: Self) -> Self {
834
9.80k
                    <$ty>::wrapping_add(self, rhs)
835
9.80k
                }
_RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int12wrapping_addCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
833
90.2k
                fn wrapping_add(self, rhs: Self) -> Self {
834
90.2k
                    <$ty>::wrapping_add(self, rhs)
835
90.2k
                }
_RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int12wrapping_addCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
833
2.16k
                fn wrapping_add(self, rhs: Self) -> Self {
834
2.16k
                    <$ty>::wrapping_add(self, rhs)
835
2.16k
                }
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int12wrapping_addCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
833
9.29k
                fn wrapping_add(self, rhs: Self) -> Self {
834
9.29k
                    <$ty>::wrapping_add(self, rhs)
835
9.29k
                }
_RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int12wrapping_addB7_
Line
Count
Source
833
11.8k
                fn wrapping_add(self, rhs: Self) -> Self {
834
11.8k
                    <$ty>::wrapping_add(self, rhs)
835
11.8k
                }
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int12wrapping_addB7_
Line
Count
Source
833
1.09k
                fn wrapping_add(self, rhs: Self) -> Self {
834
1.09k
                    <$ty>::wrapping_add(self, rhs)
835
1.09k
                }
Unexecuted instantiation: _RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs5_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredoNtB5_3Int12wrapping_addB7_
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int12wrapping_addB7_
Line
Count
Source
833
23.2k
                fn wrapping_add(self, rhs: Self) -> Self {
834
23.2k
                    <$ty>::wrapping_add(self, rhs)
835
23.2k
                }
Unexecuted instantiation: _RNvXs7_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredaNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs8_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredsNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXsa_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredxNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXsb_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurednNtB5_3Int12wrapping_addB7_
Unexecuted instantiation: _RNvXsc_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurediNtB5_3Int12wrapping_addB7_
836
837
147k
                fn wrapping_sub(self, rhs: Self) -> Self {
838
147k
                    <$ty>::wrapping_sub(self, rhs)
839
147k
                }
Unexecuted instantiation: _RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int12wrapping_subCs4eJdYXiOSk9_10wasm_smith
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int12wrapping_subCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
837
9.80k
                fn wrapping_sub(self, rhs: Self) -> Self {
838
9.80k
                    <$ty>::wrapping_sub(self, rhs)
839
9.80k
                }
_RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int12wrapping_subCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
837
90.2k
                fn wrapping_sub(self, rhs: Self) -> Self {
838
90.2k
                    <$ty>::wrapping_sub(self, rhs)
839
90.2k
                }
_RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int12wrapping_subCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
837
2.16k
                fn wrapping_sub(self, rhs: Self) -> Self {
838
2.16k
                    <$ty>::wrapping_sub(self, rhs)
839
2.16k
                }
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int12wrapping_subCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
837
9.29k
                fn wrapping_sub(self, rhs: Self) -> Self {
838
9.29k
                    <$ty>::wrapping_sub(self, rhs)
839
9.29k
                }
_RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int12wrapping_subB7_
Line
Count
Source
837
11.8k
                fn wrapping_sub(self, rhs: Self) -> Self {
838
11.8k
                    <$ty>::wrapping_sub(self, rhs)
839
11.8k
                }
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int12wrapping_subB7_
Line
Count
Source
837
1.09k
                fn wrapping_sub(self, rhs: Self) -> Self {
838
1.09k
                    <$ty>::wrapping_sub(self, rhs)
839
1.09k
                }
Unexecuted instantiation: _RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs5_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredoNtB5_3Int12wrapping_subB7_
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int12wrapping_subB7_
Line
Count
Source
837
23.2k
                fn wrapping_sub(self, rhs: Self) -> Self {
838
23.2k
                    <$ty>::wrapping_sub(self, rhs)
839
23.2k
                }
Unexecuted instantiation: _RNvXs7_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredaNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs8_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredsNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXsa_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredxNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXsb_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurednNtB5_3Int12wrapping_subB7_
Unexecuted instantiation: _RNvXsc_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurediNtB5_3Int12wrapping_subB7_
840
841
295k
                fn to_unsigned(self) -> Self::Unsigned {
842
295k
                    self as $unsigned_ty
843
295k
                }
Unexecuted instantiation: _RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int11to_unsignedCs4eJdYXiOSk9_10wasm_smith
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int11to_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
841
19.6k
                fn to_unsigned(self) -> Self::Unsigned {
842
19.6k
                    self as $unsigned_ty
843
19.6k
                }
_RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int11to_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
841
169k
                fn to_unsigned(self) -> Self::Unsigned {
842
169k
                    self as $unsigned_ty
843
169k
                }
_RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int11to_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
841
4.32k
                fn to_unsigned(self) -> Self::Unsigned {
842
4.32k
                    self as $unsigned_ty
843
4.32k
                }
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int11to_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
841
18.5k
                fn to_unsigned(self) -> Self::Unsigned {
842
18.5k
                    self as $unsigned_ty
843
18.5k
                }
_RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int11to_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
841
10.6k
                fn to_unsigned(self) -> Self::Unsigned {
842
10.6k
                    self as $unsigned_ty
843
10.6k
                }
_RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int11to_unsignedB7_
Line
Count
Source
841
23.7k
                fn to_unsigned(self) -> Self::Unsigned {
842
23.7k
                    self as $unsigned_ty
843
23.7k
                }
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int11to_unsignedB7_
Line
Count
Source
841
2.19k
                fn to_unsigned(self) -> Self::Unsigned {
842
2.19k
                    self as $unsigned_ty
843
2.19k
                }
Unexecuted instantiation: _RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs5_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredoNtB5_3Int11to_unsignedB7_
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int11to_unsignedB7_
Line
Count
Source
841
46.4k
                fn to_unsigned(self) -> Self::Unsigned {
842
46.4k
                    self as $unsigned_ty
843
46.4k
                }
Unexecuted instantiation: _RNvXs7_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredaNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs8_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredsNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXsa_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredxNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXsb_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurednNtB5_3Int11to_unsignedB7_
Unexecuted instantiation: _RNvXsc_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurediNtB5_3Int11to_unsignedB7_
844
845
147k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
147k
                    unsigned as Self
847
147k
                }
Unexecuted instantiation: _RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int13from_unsignedCs4eJdYXiOSk9_10wasm_smith
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int13from_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
845
9.80k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
9.80k
                    unsigned as Self
847
9.80k
                }
_RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int13from_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
845
84.9k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
84.9k
                    unsigned as Self
847
84.9k
                }
_RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int13from_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
845
2.16k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
2.16k
                    unsigned as Self
847
2.16k
                }
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int13from_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
845
9.29k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
9.29k
                    unsigned as Self
847
9.29k
                }
_RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int13from_unsignedCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
845
5.31k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
5.31k
                    unsigned as Self
847
5.31k
                }
_RNvXs1_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredhNtB5_3Int13from_unsignedB7_
Line
Count
Source
845
11.8k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
11.8k
                    unsigned as Self
847
11.8k
                }
_RNvXs2_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredtNtB5_3Int13from_unsignedB7_
Line
Count
Source
845
1.09k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
1.09k
                    unsigned as Self
847
1.09k
                }
Unexecuted instantiation: _RNvXs3_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredmNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs4_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredyNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs5_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredoNtB5_3Int13from_unsignedB7_
_RNvXs6_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredjNtB5_3Int13from_unsignedB7_
Line
Count
Source
845
23.2k
                fn from_unsigned(unsigned: $unsigned_ty) -> Self {
846
23.2k
                    unsigned as Self
847
23.2k
                }
Unexecuted instantiation: _RNvXs7_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredaNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs8_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredsNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXs9_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredlNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXsa_NtCsgsv2Y6Qu5CW_9arbitrary12unstructuredxNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXsb_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurednNtB5_3Int13from_unsignedB7_
Unexecuted instantiation: _RNvXsc_NtCsgsv2Y6Qu5CW_9arbitrary12unstructurediNtB5_3Int13from_unsignedB7_
848
            }
849
        )*
850
    }
851
}
852
853
impl_int! {
854
    u8: u8;
855
    u16: u16;
856
    u32: u32;
857
    u64: u64;
858
    u128: u128;
859
    usize: usize;
860
    i8: u8;
861
    i16: u16;
862
    i32: u32;
863
    i64: u64;
864
    i128: u128;
865
    isize: usize;
866
}
867
868
#[cfg(test)]
869
mod tests {
870
    use super::*;
871
872
    #[test]
873
    fn test_byte_size() {
874
        let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]);
875
        // Should take one byte off the end
876
        assert_eq!(u.arbitrary_byte_size().unwrap(), 6);
877
        assert_eq!(u.len(), 9);
878
        let mut v = vec![];
879
        v.resize(260, 0);
880
        v.push(1);
881
        v.push(4);
882
        let mut u = Unstructured::new(&v);
883
        // Should read two bytes off the end
884
        assert_eq!(u.arbitrary_byte_size().unwrap(), 0x104);
885
        assert_eq!(u.len(), 260);
886
    }
887
888
    #[test]
889
    fn int_in_range_of_one() {
890
        let mut u = Unstructured::new(&[1, 2, 3, 4, 5, 6, 7, 8, 9, 6]);
891
        let x = u.int_in_range(0..=0).unwrap();
892
        assert_eq!(x, 0);
893
        let choice = *u.choose(&[42]).unwrap();
894
        assert_eq!(choice, 42)
895
    }
896
897
    #[test]
898
    fn int_in_range_uses_minimal_amount_of_bytes() {
899
        let mut u = Unstructured::new(&[1, 2]);
900
        assert_eq!(1, u.int_in_range::<u8>(0..=u8::MAX).unwrap());
901
        assert_eq!(u.len(), 1);
902
903
        let mut u = Unstructured::new(&[1, 2]);
904
        assert_eq!(1, u.int_in_range::<u32>(0..=u8::MAX as u32).unwrap());
905
        assert_eq!(u.len(), 1);
906
907
        let mut u = Unstructured::new(&[1]);
908
        assert_eq!(1, u.int_in_range::<u32>(0..=u8::MAX as u32 + 1).unwrap());
909
        assert!(u.is_empty());
910
    }
911
912
    #[test]
913
    fn int_in_range_in_bounds() {
914
        for input in u8::MIN..=u8::MAX {
915
            let input = [input];
916
917
            let mut u = Unstructured::new(&input);
918
            let x = u.int_in_range(1..=u8::MAX).unwrap();
919
            assert_ne!(x, 0);
920
921
            let mut u = Unstructured::new(&input);
922
            let x = u.int_in_range(0..=u8::MAX - 1).unwrap();
923
            assert_ne!(x, u8::MAX);
924
        }
925
    }
926
927
    #[test]
928
    fn int_in_range_covers_unsigned_range() {
929
        // Test that we generate all values within the range given to
930
        // `int_in_range`.
931
932
        let mut full = [false; u8::MAX as usize + 1];
933
        let mut no_zero = [false; u8::MAX as usize];
934
        let mut no_max = [false; u8::MAX as usize];
935
        let mut narrow = [false; 10];
936
937
        for input in u8::MIN..=u8::MAX {
938
            let input = [input];
939
940
            let mut u = Unstructured::new(&input);
941
            let x = u.int_in_range(0..=u8::MAX).unwrap();
942
            full[x as usize] = true;
943
944
            let mut u = Unstructured::new(&input);
945
            let x = u.int_in_range(1..=u8::MAX).unwrap();
946
            no_zero[x as usize - 1] = true;
947
948
            let mut u = Unstructured::new(&input);
949
            let x = u.int_in_range(0..=u8::MAX - 1).unwrap();
950
            no_max[x as usize] = true;
951
952
            let mut u = Unstructured::new(&input);
953
            let x = u.int_in_range(100..=109).unwrap();
954
            narrow[x as usize - 100] = true;
955
        }
956
957
        for (i, covered) in full.iter().enumerate() {
958
            assert!(covered, "full[{}] should have been generated", i);
959
        }
960
        for (i, covered) in no_zero.iter().enumerate() {
961
            assert!(covered, "no_zero[{}] should have been generated", i);
962
        }
963
        for (i, covered) in no_max.iter().enumerate() {
964
            assert!(covered, "no_max[{}] should have been generated", i);
965
        }
966
        for (i, covered) in narrow.iter().enumerate() {
967
            assert!(covered, "narrow[{}] should have been generated", i);
968
        }
969
    }
970
971
    #[test]
972
    fn int_in_range_covers_signed_range() {
973
        // Test that we generate all values within the range given to
974
        // `int_in_range`.
975
976
        let mut full = [false; u8::MAX as usize + 1];
977
        let mut no_min = [false; u8::MAX as usize];
978
        let mut no_max = [false; u8::MAX as usize];
979
        let mut narrow = [false; 21];
980
981
        let abs_i8_min: isize = 128;
982
983
        for input in 0..=u8::MAX {
984
            let input = [input];
985
986
            let mut u = Unstructured::new(&input);
987
            let x = u.int_in_range(i8::MIN..=i8::MAX).unwrap();
988
            full[(x as isize + abs_i8_min) as usize] = true;
989
990
            let mut u = Unstructured::new(&input);
991
            let x = u.int_in_range(i8::MIN + 1..=i8::MAX).unwrap();
992
            no_min[(x as isize + abs_i8_min - 1) as usize] = true;
993
994
            let mut u = Unstructured::new(&input);
995
            let x = u.int_in_range(i8::MIN..=i8::MAX - 1).unwrap();
996
            no_max[(x as isize + abs_i8_min) as usize] = true;
997
998
            let mut u = Unstructured::new(&input);
999
            let x = u.int_in_range(-10..=10).unwrap();
1000
            narrow[(x as isize + 10) as usize] = true;
1001
        }
1002
1003
        for (i, covered) in full.iter().enumerate() {
1004
            assert!(covered, "full[{}] should have been generated", i);
1005
        }
1006
        for (i, covered) in no_min.iter().enumerate() {
1007
            assert!(covered, "no_min[{}] should have been generated", i);
1008
        }
1009
        for (i, covered) in no_max.iter().enumerate() {
1010
            assert!(covered, "no_max[{}] should have been generated", i);
1011
        }
1012
        for (i, covered) in narrow.iter().enumerate() {
1013
            assert!(covered, "narrow[{}] should have been generated", i);
1014
        }
1015
    }
1016
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/flagset-0.4.5/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//
2
// Copyright 2019 Red Hat, Inc.
3
//
4
// Author: Nathaniel McCallum <npmccallum@redhat.com>
5
//
6
// Licensed under the Apache License, Version 2.0 (the "License");
7
// you may not use this file except in compliance with the License.
8
// You may obtain a copy of the License at
9
//
10
//     http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software
13
// distributed under the License is distributed on an "AS IS" BASIS,
14
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
// See the License for the specific language governing permissions and
16
// limitations under the License.
17
//
18
19
//! # Welcome to FlagSet!
20
//!
21
//! FlagSet is a new, ergonomic approach to handling flags that combines the
22
//! best of existing crates like `bitflags` and `enumflags` without their
23
//! downsides.
24
//!
25
//! ## Existing Implementations
26
//!
27
//! The `bitflags` crate has long been part of the Rust ecosystem.
28
//! Unfortunately, it doesn't feel like natural Rust. The `bitflags` crate
29
//! uses a wierd struct format to define flags. Flags themselves are just
30
//! integers constants, so there is little type-safety involved. But it doesn't
31
//! have any dependencies. It also allows you to define implied flags (otherwise
32
//! known as overlapping flags).
33
//!
34
//! The `enumflags` crate tried to improve on `bitflags` by using enumerations
35
//! to define flags. This was a big improvement to the natural feel of the code.
36
//! Unfortunately, there are some design flaws. To generate the flags,
37
//! procedural macros were used. This implied two separate crates plus
38
//! additional dependencies. Further, `enumflags` specifies the size of the
39
//! flags using a `repr($size)` attribute. Unfortunately, this attribute
40
//! cannot resolve type aliases, such as `c_int`. This makes `enumflags` a
41
//! poor fit for FFI, which is the most important place for a flags library.
42
//! The `enumflags` crate also disallows overlapping flags and is not
43
//! maintained.
44
//!
45
//! FlagSet improves on both of these by adopting the `enumflags` natural feel
46
//! and the `bitflags` mode of flag generation; as well as additional API usage
47
//! niceties. FlagSet has no dependencies and is extensively documented and
48
//! tested. It also tries very hard to prevent you from making mistakes by
49
//! avoiding external usage of the integer types. FlagSet is also a zero-cost
50
//! abstraction: all functions are inlineable and should reduce to the core
51
//! integer operations. FlagSet also does not depend on stdlib, so it can be
52
//! used in `no_std` libraries and applications.
53
//!
54
//! ## Defining Flags
55
//!
56
//! Flags are defined using the `flags!` macro:
57
//!
58
//! ```
59
//! use flagset::{FlagSet, flags};
60
//! use std::os::raw::c_int;
61
//!
62
//! flags! {
63
//!     enum FlagsA: u8 {
64
//!         Foo,
65
//!         Bar,
66
//!         Baz,
67
//!     }
68
//!
69
//!     enum FlagsB: c_int {
70
//!         Foo,
71
//!         Bar,
72
//!         Baz,
73
//!     }
74
//! }
75
//! ```
76
//!
77
//! Notice that a flag definition looks just like a regular enumeration, with
78
//! the addition of the field-size type. The field-size type is required and
79
//! can be either a type or a type alias. Both examples are given above.
80
//!
81
//! Also note that the field-size type specifies the size of the corresponding
82
//! `FlagSet` type, not size of the enumeration itself. To specify the size of
83
//! the enumeration, use the `repr($size)` attribute as specified below.
84
//!
85
//! ## Flag Values
86
//!
87
//! Flags often need values assigned to them. This can be done implicitly,
88
//! where the value depends on the order of the flags:
89
//!
90
//! ```
91
//! use flagset::{FlagSet, flags};
92
//!
93
//! flags! {
94
//!     enum Flags: u16 {
95
//!         Foo, // Implicit Value: 0b0001
96
//!         Bar, // Implicit Value: 0b0010
97
//!         Baz, // Implicit Value: 0b0100
98
//!     }
99
//! }
100
//! ```
101
//!
102
//! Alternatively, flag values can be defined explicitly, by specifying any
103
//! `const` expression:
104
//!
105
//! ```
106
//! use flagset::{FlagSet, flags};
107
//!
108
//! flags! {
109
//!     enum Flags: u16 {
110
//!         Foo = 0x01,   // Explicit Value: 0b0001
111
//!         Bar = 2,      // Explicit Value: 0b0010
112
//!         Baz = 0b0100, // Explicit Value: 0b0100
113
//!     }
114
//! }
115
//! ```
116
//!
117
//! Flags can also overlap or "imply" other flags:
118
//!
119
//! ```
120
//! use flagset::{FlagSet, flags};
121
//!
122
//! flags! {
123
//!     enum Flags: u16 {
124
//!         Foo = 0b0001,
125
//!         Bar = 0b0010,
126
//!         Baz = 0b0110, // Implies Bar
127
//!         All = (Flags::Foo | Flags::Bar | Flags::Baz).bits(),
128
//!     }
129
//! }
130
//! ```
131
//!
132
//! ## Specifying Attributes
133
//!
134
//! Attributes can be used on the enumeration itself or any of the values:
135
//!
136
//! ```
137
//! use flagset::{FlagSet, flags};
138
//!
139
//! flags! {
140
//!     #[derive(PartialOrd, Ord)]
141
//!     enum Flags: u8 {
142
//!         Foo,
143
//!         #[deprecated]
144
//!         Bar,
145
//!         Baz,
146
//!     }
147
//! }
148
//! ```
149
//!
150
//! ## Collections of Flags
151
//!
152
//! A collection of flags is a `FlagSet<T>`. If you are storing the flags in
153
//! memory, the raw `FlagSet<T>` type should be used. However, if you want to
154
//! receive flags as an input to a function, you should use
155
//! `impl Into<FlagSet<T>>`. This allows for very ergonomic APIs:
156
//!
157
//! ```
158
//! use flagset::{FlagSet, flags};
159
//!
160
//! flags! {
161
//!     enum Flags: u8 {
162
//!         Foo,
163
//!         Bar,
164
//!         Baz,
165
//!     }
166
//! }
167
//!
168
//! struct Container(FlagSet<Flags>);
169
//!
170
//! impl Container {
171
//!     fn new(flags: impl Into<FlagSet<Flags>>) -> Container {
172
//!         Container(flags.into())
173
//!     }
174
//! }
175
//!
176
//! assert_eq!(Container::new(Flags::Foo | Flags::Bar).0.bits(), 0b011);
177
//! assert_eq!(Container::new(Flags::Foo).0.bits(), 0b001);
178
//! assert_eq!(Container::new(None).0.bits(), 0b000);
179
//! ```
180
//!
181
//! ## Operations
182
//!
183
//! Operations can be performed on a `FlagSet<F>` or on individual flags:
184
//!
185
//! | Operator | Assignment Operator | Meaning                |
186
//! |----------|---------------------|------------------------|
187
//! | \|       | \|=                 | Union                  |
188
//! | &        | &=                  | Intersection           |
189
//! | ^        | ^=                  | Toggle specified flags |
190
//! | -        | -=                  | Difference             |
191
//! | %        | %=                  | Symmetric difference   |
192
//! | !        |                     | Toggle all flags       |
193
//!
194
#![cfg_attr(
195
    feature = "serde",
196
    doc = r#"
197
198
## Optional Serde support
199
200
[Serde] support can be enabled with the 'serde' feature flag. You can then serialize and
201
deserialize `FlagSet<T>` to and from any of the [supported formats]:
202
203
 ```
204
 use flagset::{FlagSet, flags};
205
206
 flags! {
207
     enum Flags: u8 {
208
         Foo,
209
         Bar,
210
     }
211
 }
212
213
 let flagset = Flags::Foo | Flags::Bar;
214
 let json = serde_json::to_string(&flagset).unwrap();
215
 let flagset: FlagSet<Flags> = serde_json::from_str(&json).unwrap();
216
 assert_eq!(flagset.bits(), 0b011);
217
 ```
218
219
For serialization and deserialization of flags enum itself, you can use the [`serde_repr`] crate
220
(or implement `serde::ser::Serialize` and `serde:de::Deserialize` manually), combined with the
221
appropriate `repr` attribute:
222
223
 ```
224
 use flagset::{FlagSet, flags};
225
 use serde_repr::{Serialize_repr, Deserialize_repr};
226
227
 flags! {
228
    #[repr(u8)]
229
    #[derive(Deserialize_repr, Serialize_repr)]
230
    enum Flags: u8 {
231
         Foo,
232
         Bar,
233
    }
234
 }
235
236
 let json = serde_json::to_string(&Flags::Foo).unwrap();
237
 let flag: Flags = serde_json::from_str(&json).unwrap();
238
 assert_eq!(flag, Flags::Foo);
239
 ```
240
241
[Serde]: https://serde.rs/
242
[supported formats]: https://serde.rs/#data-formats
243
[`serde_repr`]: https://crates.io/crates/serde_repr
244
"#
245
)]
246
#![allow(unknown_lints)]
247
#![warn(clippy::all)]
248
#![cfg_attr(not(feature = "std"), no_std)]
249
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
250
251
use core::fmt::{Debug, Formatter, Result};
252
use core::ops::*;
253
254
/// Error type returned when creating a new flagset from bits is invalid or undefined.
255
/// ```
256
/// use flagset::{FlagSet, flags};
257
///
258
/// flags! {
259
///     pub enum Flag: u16 {
260
///         Foo = 0b0001,
261
///         Bar = 0b0010,
262
///         Baz = 0b0100,
263
///         Qux = 0b1010, // Implies Bar
264
///     }
265
/// }
266
///
267
/// assert_eq!(FlagSet::<Flag>::new(0b01101), Err(flagset::InvalidBits)); // Invalid
268
/// assert_eq!(FlagSet::<Flag>::new(0b10101), Err(flagset::InvalidBits)); // Unknown
269
/// ```
270
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
271
pub struct InvalidBits;
272
273
impl core::fmt::Display for InvalidBits {
274
    #[inline]
275
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
276
        write!(f, "invalid bits")
277
    }
278
}
279
280
#[cfg(feature = "std")]
281
impl std::error::Error for InvalidBits {}
282
283
#[doc(hidden)]
284
pub trait Flags:
285
    Copy
286
    + Clone
287
    + Debug
288
    + PartialEq
289
    + Eq
290
    + BitAnd<Self, Output = FlagSet<Self>>
291
    + BitOr<Self, Output = FlagSet<Self>>
292
    + BitXor<Self, Output = FlagSet<Self>>
293
    + Sub<Self, Output = FlagSet<Self>>
294
    + Rem<Self, Output = FlagSet<Self>>
295
    + Not<Output = FlagSet<Self>>
296
    + Into<FlagSet<Self>>
297
    + 'static
298
{
299
    type Type: Copy
300
        + Clone
301
        + Debug
302
        + PartialEq
303
        + Eq
304
        + Default
305
        + BitAnd<Self::Type, Output = Self::Type>
306
        + BitAndAssign<Self::Type>
307
        + BitOr<Self::Type, Output = Self::Type>
308
        + BitOrAssign<Self::Type>
309
        + BitXor<Self::Type, Output = Self::Type>
310
        + BitXorAssign<Self::Type>
311
        + Not<Output = Self::Type>;
312
313
    /// A slice containing all the possible flag values.
314
    const LIST: &'static [Self];
315
316
    /// Creates an empty `FlagSet` of this type
317
    #[inline]
318
0
    fn none() -> FlagSet<Self> {
319
0
        FlagSet::default()
320
0
    }
321
}
322
323
#[derive(Copy, Clone, Eq, Hash)]
324
pub struct FlagSet<F: Flags>(F::Type);
325
326
#[doc(hidden)]
327
#[derive(Copy, Clone)]
328
pub struct Iter<F: Flags>(FlagSet<F>, usize);
329
330
impl<F: Flags> Iterator for Iter<F> {
331
    type Item = F;
332
333
    #[inline]
334
0
    fn next(&mut self) -> Option<Self::Item> {
335
0
        while self.1 < F::LIST.len() {
336
0
            let next = F::LIST[self.1];
337
0
            self.1 += 1;
338
0
339
0
            if self.0.contains(next) {
340
0
                return Some(next);
341
0
            }
342
        }
343
344
0
        None
345
0
    }
346
}
347
348
impl<F: Flags> IntoIterator for FlagSet<F> {
349
    type Item = F;
350
    type IntoIter = Iter<F>;
351
352
    /// Iterate over the flags in the set.
353
    ///
354
    /// **NOTE**: The order in which the flags are iterated is undefined.
355
    ///
356
    /// ```
357
    /// use flagset::{FlagSet, flags};
358
    ///
359
    /// flags! {
360
    ///     enum Flag: u8 {
361
    ///         Foo = 0b001,
362
    ///         Bar = 0b010,
363
    ///         Baz = 0b100
364
    ///     }
365
    /// }
366
    ///
367
    /// let set = Flag::Foo | Flag::Bar;
368
    /// let mut iter = set.into_iter();
369
    /// assert_eq!(iter.next(), Some(Flag::Foo));
370
    /// assert_eq!(iter.next(), Some(Flag::Bar));
371
    /// assert_eq!(iter.next(), None);
372
    /// ```
373
    #[inline]
374
0
    fn into_iter(self) -> Self::IntoIter {
375
0
        Iter(self, 0)
376
0
    }
377
}
378
379
impl<F: Flags> Debug for FlagSet<F> {
380
    #[inline]
381
0
    fn fmt(&self, f: &mut Formatter) -> Result {
382
0
        write!(f, "FlagSet(")?;
383
0
        for (i, flag) in self.into_iter().enumerate() {
384
0
            write!(f, "{}{:?}", if i > 0 { " | " } else { "" }, flag)?;
385
        }
386
0
        write!(f, ")")
387
0
    }
388
}
389
390
impl<F: Flags, R: Copy + Into<FlagSet<F>>> PartialEq<R> for FlagSet<F> {
391
    #[inline]
392
2.51M
    fn eq(&self, rhs: &R) -> bool {
393
2.51M
        self.0 == (*rhs).into().0
394
2.51M
    }
395
}
396
397
impl<F: Flags> AsRef<F::Type> for FlagSet<F> {
398
    #[inline]
399
    fn as_ref(&self) -> &F::Type {
400
        &self.0
401
    }
402
}
403
404
impl<F: Flags> From<Option<FlagSet<F>>> for FlagSet<F> {
405
    /// Converts from `Option<FlagSet<F>>` to `FlagSet<F>`.
406
    ///
407
    /// Most notably, this allows for the use of `None` in many places to
408
    /// substitute for manually creating an empty `FlagSet<F>`. See below.
409
    ///
410
    /// ```
411
    /// use flagset::{FlagSet, flags};
412
    ///
413
    /// flags! {
414
    ///     enum Flag: u8 {
415
    ///         Foo = 0b001,
416
    ///         Bar = 0b010,
417
    ///         Baz = 0b100
418
    ///     }
419
    /// }
420
    ///
421
    /// fn convert(v: impl Into<FlagSet<Flag>>) -> u8 {
422
    ///     v.into().bits()
423
    /// }
424
    ///
425
    /// assert_eq!(convert(Flag::Foo | Flag::Bar), 0b011);
426
    /// assert_eq!(convert(Flag::Foo), 0b001);
427
    /// assert_eq!(convert(None), 0b000);
428
    /// ```
429
    #[inline]
430
    fn from(value: Option<FlagSet<F>>) -> FlagSet<F> {
431
        value.unwrap_or_default()
432
    }
433
}
434
435
impl<F: Flags> Default for FlagSet<F> {
436
    /// Creates a new, empty FlagSet.
437
    ///
438
    /// ```
439
    /// use flagset::{FlagSet, flags};
440
    ///
441
    /// flags! {
442
    ///     enum Flag: u8 {
443
    ///         Foo = 0b001,
444
    ///         Bar = 0b010,
445
    ///         Baz = 0b100
446
    ///     }
447
    /// }
448
    ///
449
    /// let set = FlagSet::<Flag>::default();
450
    /// assert!(set.is_empty());
451
    /// assert!(!set.is_full());
452
    /// assert!(!set.contains(Flag::Foo));
453
    /// assert!(!set.contains(Flag::Bar));
454
    /// assert!(!set.contains(Flag::Baz));
455
    /// ```
456
    #[inline]
457
5.67k
    fn default() -> Self {
458
5.67k
        FlagSet(F::Type::default())
459
5.67k
    }
460
}
461
462
impl<F: Flags> Not for FlagSet<F> {
463
    type Output = Self;
464
465
    /// Calculates the complement of the current set.
466
    ///
467
    /// In common parlance, this returns the set of all possible flags that are
468
    /// not in the current set.
469
    ///
470
    /// ```
471
    /// use flagset::{FlagSet, flags};
472
    ///
473
    /// flags! {
474
    ///     #[derive(PartialOrd, Ord)]
475
    ///     enum Flag: u8 {
476
    ///         Foo = 1 << 0,
477
    ///         Bar = 1 << 1,
478
    ///         Baz = 1 << 2
479
    ///     }
480
    /// }
481
    ///
482
    /// let set = !FlagSet::from(Flag::Foo);
483
    /// assert!(!set.is_empty());
484
    /// assert!(!set.is_full());
485
    /// assert!(!set.contains(Flag::Foo));
486
    /// assert!(set.contains(Flag::Bar));
487
    /// assert!(set.contains(Flag::Baz));
488
    /// ```
489
    #[inline]
490
0
    fn not(self) -> Self {
491
0
        FlagSet(!self.0)
492
0
    }
493
}
494
495
impl<F: Flags, R: Into<FlagSet<F>>> BitAnd<R> for FlagSet<F> {
496
    type Output = Self;
497
498
    /// Calculates the intersection of the current set and the specified flags.
499
    ///
500
    /// ```
501
    /// use flagset::{FlagSet, flags};
502
    ///
503
    /// flags! {
504
    ///     #[derive(PartialOrd, Ord)]
505
    ///     pub enum Flag: u8 {
506
    ///         Foo = 0b001,
507
    ///         Bar = 0b010,
508
    ///         Baz = 0b100
509
    ///     }
510
    /// }
511
    ///
512
    /// let set0 = Flag::Foo | Flag::Bar;
513
    /// let set1 = Flag::Baz | Flag::Bar;
514
    /// assert_eq!(set0 & set1, Flag::Bar);
515
    /// assert_eq!(set0 & Flag::Foo, Flag::Foo);
516
    /// assert_eq!(set1 & Flag::Baz, Flag::Baz);
517
    /// ```
518
    #[inline]
519
2.51M
    fn bitand(self, rhs: R) -> Self {
520
2.51M
        FlagSet(self.0 & rhs.into().0)
521
2.51M
    }
522
}
523
524
impl<F: Flags, R: Into<FlagSet<F>>> BitAndAssign<R> for FlagSet<F> {
525
    /// Assigns the intersection of the current set and the specified flags.
526
    ///
527
    /// ```
528
    /// use flagset::{FlagSet, flags};
529
    ///
530
    /// flags! {
531
    ///     enum Flag: u64 {
532
    ///         Foo = 0b001,
533
    ///         Bar = 0b010,
534
    ///         Baz = 0b100
535
    ///     }
536
    /// }
537
    ///
538
    /// let mut set0 = Flag::Foo | Flag::Bar;
539
    /// let mut set1 = Flag::Baz | Flag::Bar;
540
    ///
541
    /// set0 &= set1;
542
    /// assert_eq!(set0, Flag::Bar);
543
    ///
544
    /// set1 &= Flag::Baz;
545
    /// assert_eq!(set0, Flag::Bar);
546
    /// ```
547
    #[inline]
548
    fn bitand_assign(&mut self, rhs: R) {
549
        self.0 &= rhs.into().0
550
    }
551
}
552
553
impl<F: Flags, R: Into<FlagSet<F>>> BitOr<R> for FlagSet<F> {
554
    type Output = Self;
555
556
    /// Calculates the union of the current set with the specified flags.
557
    ///
558
    /// ```
559
    /// use flagset::{FlagSet, flags};
560
    ///
561
    /// flags! {
562
    ///     #[derive(PartialOrd, Ord)]
563
    ///     pub enum Flag: u8 {
564
    ///         Foo = 0b001,
565
    ///         Bar = 0b010,
566
    ///         Baz = 0b100
567
    ///     }
568
    /// }
569
    ///
570
    /// let set0 = Flag::Foo | Flag::Bar;
571
    /// let set1 = Flag::Baz | Flag::Bar;
572
    /// assert_eq!(set0 | set1, FlagSet::full());
573
    /// ```
574
    #[inline]
575
0
    fn bitor(self, rhs: R) -> Self {
576
0
        FlagSet(self.0 | rhs.into().0)
577
0
    }
578
}
579
580
impl<F: Flags, R: Into<FlagSet<F>>> BitOrAssign<R> for FlagSet<F> {
581
    /// Assigns the union of the current set with the specified flags.
582
    ///
583
    /// ```
584
    /// use flagset::{FlagSet, flags};
585
    ///
586
    /// flags! {
587
    ///     enum Flag: u64 {
588
    ///         Foo = 0b001,
589
    ///         Bar = 0b010,
590
    ///         Baz = 0b100
591
    ///     }
592
    /// }
593
    ///
594
    /// let mut set0 = Flag::Foo | Flag::Bar;
595
    /// let mut set1 = Flag::Bar | Flag::Baz;
596
    ///
597
    /// set0 |= set1;
598
    /// assert_eq!(set0, FlagSet::full());
599
    ///
600
    /// set1 |= Flag::Baz;
601
    /// assert_eq!(set1, Flag::Bar | Flag::Baz);
602
    /// ```
603
    #[inline]
604
51.0k
    fn bitor_assign(&mut self, rhs: R) {
605
51.0k
        self.0 |= rhs.into().0
606
51.0k
    }
607
}
608
609
impl<F: Flags, R: Into<FlagSet<F>>> BitXor<R> for FlagSet<F> {
610
    type Output = Self;
611
612
    /// Calculates the current set with the specified flags toggled.
613
    ///
614
    /// This is commonly known as toggling the presence
615
    ///
616
    /// ```
617
    /// use flagset::{FlagSet, flags};
618
    ///
619
    /// flags! {
620
    ///     enum Flag: u32 {
621
    ///         Foo = 0b001,
622
    ///         Bar = 0b010,
623
    ///         Baz = 0b100
624
    ///     }
625
    /// }
626
    ///
627
    /// let set0 = Flag::Foo | Flag::Bar;
628
    /// let set1 = Flag::Baz | Flag::Bar;
629
    /// assert_eq!(set0 ^ set1, Flag::Foo | Flag::Baz);
630
    /// assert_eq!(set0 ^ Flag::Foo, Flag::Bar);
631
    /// ```
632
    #[inline]
633
    fn bitxor(self, rhs: R) -> Self {
634
        FlagSet(self.0 ^ rhs.into().0)
635
    }
636
}
637
638
impl<F: Flags, R: Into<FlagSet<F>>> BitXorAssign<R> for FlagSet<F> {
639
    /// Assigns the current set with the specified flags toggled.
640
    ///
641
    /// ```
642
    /// use flagset::{FlagSet, flags};
643
    ///
644
    /// flags! {
645
    ///     enum Flag: u16 {
646
    ///         Foo = 0b001,
647
    ///         Bar = 0b010,
648
    ///         Baz = 0b100
649
    ///     }
650
    /// }
651
    ///
652
    /// let mut set0 = Flag::Foo | Flag::Bar;
653
    /// let mut set1 = Flag::Baz | Flag::Bar;
654
    ///
655
    /// set0 ^= set1;
656
    /// assert_eq!(set0, Flag::Foo | Flag::Baz);
657
    ///
658
    /// set1 ^= Flag::Baz;
659
    /// assert_eq!(set1, Flag::Bar);
660
    /// ```
661
    #[inline]
662
    fn bitxor_assign(&mut self, rhs: R) {
663
        self.0 ^= rhs.into().0
664
    }
665
}
666
667
impl<F: Flags, R: Into<FlagSet<F>>> Sub<R> for FlagSet<F> {
668
    type Output = Self;
669
670
    /// Calculates set difference (the current set without the specified flags).
671
    ///
672
    /// ```
673
    /// use flagset::{FlagSet, flags};
674
    ///
675
    /// flags! {
676
    ///     pub enum Flag: u8 {
677
    ///         Foo = 1,
678
    ///         Bar = 2,
679
    ///         Baz = 4
680
    ///     }
681
    /// }
682
    ///
683
    /// let set0 = Flag::Foo | Flag::Bar;
684
    /// let set1 = Flag::Baz | Flag::Bar;
685
    /// assert_eq!(set0 - set1, Flag::Foo);
686
    /// ```
687
    #[inline]
688
    fn sub(self, rhs: R) -> Self {
689
        self & !rhs.into()
690
    }
691
}
692
693
impl<F: Flags, R: Into<FlagSet<F>>> SubAssign<R> for FlagSet<F> {
694
    /// Assigns set difference (the current set without the specified flags).
695
    ///
696
    /// ```
697
    /// use flagset::{FlagSet, flags};
698
    ///
699
    /// flags! {
700
    ///     pub enum Flag: u8 {
701
    ///         Foo = 1,
702
    ///         Bar = 2,
703
    ///         Baz = 4
704
    ///     }
705
    /// }
706
    ///
707
    /// let mut set0 = Flag::Foo | Flag::Bar;
708
    /// set0 -= Flag::Baz | Flag::Bar;
709
    /// assert_eq!(set0, Flag::Foo);
710
    /// ```
711
    #[inline]
712
    fn sub_assign(&mut self, rhs: R) {
713
        *self &= !rhs.into();
714
    }
715
}
716
717
impl<F: Flags, R: Into<FlagSet<F>>> Rem<R> for FlagSet<F> {
718
    type Output = Self;
719
720
    /// Calculates the symmetric difference between two sets.
721
    ///
722
    /// The symmetric difference between two sets is the set of all flags
723
    /// that appear in one set or the other, but not both.
724
    ///
725
    /// ```
726
    /// use flagset::{FlagSet, flags};
727
    ///
728
    /// flags! {
729
    ///     pub enum Flag: u8 {
730
    ///         Foo = 1,
731
    ///         Bar = 2,
732
    ///         Baz = 4
733
    ///     }
734
    /// }
735
    ///
736
    /// let set0 = Flag::Foo | Flag::Bar;
737
    /// let set1 = Flag::Baz | Flag::Bar;
738
    /// assert_eq!(set0 % set1, Flag::Foo | Flag::Baz);
739
    /// ```
740
    #[inline]
741
    fn rem(self, rhs: R) -> Self {
742
        let rhs = rhs.into();
743
        (self - rhs) | (rhs - self)
744
    }
745
}
746
747
impl<F: Flags, R: Into<FlagSet<F>>> RemAssign<R> for FlagSet<F> {
748
    /// Assigns the symmetric difference between two sets.
749
    ///
750
    /// The symmetric difference between two sets is the set of all flags
751
    /// that appear in one set or the other, but not both.
752
    ///
753
    /// ```
754
    /// use flagset::{FlagSet, flags};
755
    ///
756
    /// flags! {
757
    ///     pub enum Flag: u8 {
758
    ///         Foo = 1,
759
    ///         Bar = 2,
760
    ///         Baz = 4
761
    ///     }
762
    /// }
763
    ///
764
    /// let mut set0 = Flag::Foo | Flag::Bar;
765
    /// let set1 = Flag::Baz | Flag::Bar;
766
    /// set0 %= set1;
767
    /// assert_eq!(set0, Flag::Foo | Flag::Baz);
768
    /// ```
769
    #[inline]
770
    fn rem_assign(&mut self, rhs: R) {
771
        *self = *self % rhs
772
    }
773
}
774
775
impl<F: Flags, R: Into<FlagSet<F>>> Extend<R> for FlagSet<F> {
776
    /// Add values by iterating over some collection.
777
    ///
778
    /// ```
779
    /// use flagset::{FlagSet, flags};
780
    ///
781
    /// flags! {
782
    ///     pub enum Flag: u8 {
783
    ///         Foo = 1,
784
    ///         Bar = 2,
785
    ///         Baz = 4
786
    ///     }
787
    /// }
788
    ///
789
    /// let flag_vec = vec![Flag::Bar, Flag::Baz];
790
    /// let mut some_extended_flags = FlagSet::from(Flag::Foo);
791
    /// some_extended_flags.extend(flag_vec);
792
    /// assert_eq!(some_extended_flags, Flag::Foo | Flag::Bar | Flag::Baz);
793
    /// ```
794
    fn extend<T>(&mut self, iter: T)
795
    where
796
        T: IntoIterator<Item = R>,
797
    {
798
        for item in iter {
799
            *self |= item;
800
        }
801
    }
802
}
803
804
impl<F: Flags> FlagSet<F> {
805
    /// Creates a new set from bits; returning `Err(InvalidBits)` on invalid/unknown bits.
806
    ///
807
    /// ```
808
    /// use flagset::{FlagSet, flags};
809
    ///
810
    /// flags! {
811
    ///     pub enum Flag: u16 {
812
    ///         Foo = 0b0001,
813
    ///         Bar = 0b0010,
814
    ///         Baz = 0b0100,
815
    ///         Qux = 0b1010, // Implies Bar
816
    ///     }
817
    /// }
818
    ///
819
    /// assert_eq!(FlagSet::<Flag>::new(0b00101), Ok(Flag::Foo | Flag::Baz));
820
    /// assert_eq!(FlagSet::<Flag>::new(0b01101), Err(flagset::InvalidBits)); // Invalid
821
    /// assert_eq!(FlagSet::<Flag>::new(0b10101), Err(flagset::InvalidBits)); // Unknown
822
    /// ```
823
    #[inline]
824
    pub fn new(bits: F::Type) -> core::result::Result<Self, InvalidBits> {
825
        if Self::new_truncated(bits).0 == bits {
826
            return Ok(FlagSet(bits));
827
        }
828
829
        Err(InvalidBits)
830
    }
831
832
    /// Creates a new set from bits; truncating invalid/unknown bits.
833
    ///
834
    /// ```
835
    /// use flagset::{FlagSet, flags};
836
    ///
837
    /// flags! {
838
    ///     pub enum Flag: u16 {
839
    ///         Foo = 0b0001,
840
    ///         Bar = 0b0010,
841
    ///         Baz = 0b0100,
842
    ///         Qux = 0b1010, // Implies Bar
843
    ///     }
844
    /// }
845
    ///
846
    /// let set = FlagSet::new_truncated(0b11101);  // Has invalid and unknown.
847
    /// assert_eq!(set, Flag::Foo | Flag::Baz);
848
    /// assert_eq!(set.bits(), 0b00101);            // Has neither.
849
    /// ```
850
    #[inline]
851
    pub fn new_truncated(bits: F::Type) -> Self {
852
        let mut set = Self::default();
853
854
        for flag in FlagSet::<F>(bits) {
855
            set |= flag;
856
        }
857
858
        set
859
    }
860
861
    /// Creates a new set from bits; use of invalid/unknown bits is undefined.
862
    ///
863
    /// ```
864
    /// use flagset::{FlagSet, flags};
865
    ///
866
    /// flags! {
867
    ///     pub enum Flag: u16 {
868
    ///         Foo = 0b0001,
869
    ///         Bar = 0b0010,
870
    ///         Baz = 0b0100,
871
    ///         Qux = 0b1010, // Implies Bar
872
    ///     }
873
    /// }
874
    ///
875
    /// // Unknown and invalid bits are retained. Behavior is undefined.
876
    /// const set: FlagSet<Flag> = unsafe { FlagSet::<Flag>::new_unchecked(0b11101) };
877
    /// assert_eq!(set.bits(), 0b11101);
878
    /// ```
879
    ///
880
    /// # Safety
881
    ///
882
    /// This constructor doesn't check that the bits are valid. If you pass
883
    /// undefined flags, undefined behavior may result.
884
    #[inline]
885
2.56M
    pub const unsafe fn new_unchecked(bits: F::Type) -> Self {
886
2.56M
        FlagSet(bits)
887
2.56M
    }
888
889
    /// Creates a new FlagSet containing all possible flags.
890
    ///
891
    /// ```
892
    /// use flagset::{FlagSet, flags};
893
    ///
894
    /// flags! {
895
    ///     pub enum Flag: u8 {
896
    ///         Foo = 1,
897
    ///         Bar = 2,
898
    ///         Baz = 4
899
    ///     }
900
    /// }
901
    ///
902
    /// let set = FlagSet::full();
903
    /// assert!(!set.is_empty());
904
    /// assert!(set.is_full());
905
    /// assert!(set.contains(Flag::Foo));
906
    /// assert!(set.contains(Flag::Bar));
907
    /// assert!(set.contains(Flag::Baz));
908
    /// ```
909
    #[inline]
910
5.67k
    pub fn full() -> Self {
911
5.67k
        let mut set = Self::default();
912
56.7k
        for f in F::LIST {
913
51.0k
            set |= *f
914
        }
915
5.67k
        set
916
5.67k
    }
917
918
    /// Returns the raw bits of the set.
919
    ///
920
    /// ```
921
    /// use flagset::{FlagSet, flags};
922
    ///
923
    /// flags! {
924
    ///     pub enum Flag: u16 {
925
    ///         Foo = 0b0001,
926
    ///         Bar = 0b0010,
927
    ///         Baz = 0b0100,
928
    ///     }
929
    /// }
930
    ///
931
    /// let set = Flag::Foo | Flag::Baz;
932
    /// assert_eq!(set.bits(), 0b0101u16);
933
    /// ```
934
    #[inline]
935
    pub fn bits(self) -> F::Type {
936
        self.0
937
    }
938
939
    /// Returns true if the FlagSet contains no flags.
940
    ///
941
    /// ```
942
    /// use flagset::{FlagSet, flags};
943
    ///
944
    /// flags! {
945
    ///     pub enum Flag: u8 {
946
    ///         Foo = 1,
947
    ///         Bar = 2,
948
    ///         Baz = 4
949
    ///     }
950
    /// }
951
    ///
952
    /// let mut set = Flag::Foo | Flag::Bar;
953
    /// assert!(!set.is_empty());
954
    ///
955
    /// set &= Flag::Baz;
956
    /// assert!(set.is_empty());
957
    /// ```
958
    #[inline]
959
    pub fn is_empty(self) -> bool {
960
        self == Self::default()
961
    }
962
963
    /// Returns true if the FlagSet contains all possible flags.
964
    ///
965
    /// ```
966
    /// use flagset::{FlagSet, flags};
967
    ///
968
    /// flags! {
969
    ///     pub enum Flag: u8 {
970
    ///         Foo = 1,
971
    ///         Bar = 2,
972
    ///         Baz = 4
973
    ///     }
974
    /// }
975
    ///
976
    /// let mut set = Flag::Foo | Flag::Bar;
977
    /// assert!(!set.is_full());
978
    ///
979
    /// set |= Flag::Baz;
980
    /// assert!(set.is_full());
981
    /// ```
982
    #[inline]
983
    pub fn is_full(self) -> bool {
984
        self == Self::full()
985
    }
986
987
    /// Returns true if the two `FlagSet`s do not share any flags.
988
    ///
989
    /// ```
990
    /// use flagset::{FlagSet, flags};
991
    ///
992
    /// flags! {
993
    ///     pub enum Flag: u8 {
994
    ///         Foo = 1,
995
    ///         Bar = 2,
996
    ///         Baz = 4
997
    ///     }
998
    /// }
999
    ///
1000
    /// let set = Flag::Foo | Flag::Bar;
1001
    /// assert!(!set.is_disjoint(Flag::Foo));
1002
    /// assert!(!set.is_disjoint(Flag::Foo | Flag::Baz));
1003
    /// assert!(set.is_disjoint(Flag::Baz));
1004
    /// ```
1005
    #[inline]
1006
    pub fn is_disjoint(self, rhs: impl Into<FlagSet<F>>) -> bool {
1007
        self & rhs == Self::default()
1008
    }
1009
1010
    /// Returns true if this FlagSet is a superset of the specified flags.
1011
    ///
1012
    /// ```
1013
    /// use flagset::{FlagSet, flags};
1014
    ///
1015
    /// flags! {
1016
    ///     pub enum Flag: u8 {
1017
    ///         Foo = 1,
1018
    ///         Bar = 2,
1019
    ///         Baz = 4
1020
    ///     }
1021
    /// }
1022
    ///
1023
    /// let set = Flag::Foo | Flag::Bar;
1024
    /// assert!(set.contains(Flag::Foo));
1025
    /// assert!(set.contains(Flag::Foo | Flag::Bar));
1026
    /// assert!(!set.contains(Flag::Foo | Flag::Bar | Flag::Baz));
1027
    /// ```
1028
    #[inline]
1029
2.51M
    pub fn contains(self, rhs: impl Into<FlagSet<F>>) -> bool {
1030
2.51M
        let rhs = rhs.into();
1031
2.51M
        self & rhs == rhs
1032
2.51M
    }
1033
1034
    /// Removes all flags from the FlagSet.
1035
    ///
1036
    /// ```
1037
    /// use flagset::{FlagSet, flags};
1038
    ///
1039
    /// flags! {
1040
    ///     pub enum Flag: u8 {
1041
    ///         Foo = 1,
1042
    ///         Bar = 2,
1043
    ///         Baz = 4
1044
    ///     }
1045
    /// }
1046
    ///
1047
    /// let mut set = Flag::Foo | Flag::Bar;
1048
    /// assert!(!set.is_empty());
1049
    ///
1050
    /// set.clear();
1051
    /// assert!(set.is_empty());
1052
    /// ```
1053
    #[inline]
1054
    pub fn clear(&mut self) {
1055
        *self = Self::default();
1056
    }
1057
1058
    /// Clears the current set and returns an iterator of all removed flags.
1059
    ///
1060
    /// ```
1061
    /// use flagset::{FlagSet, flags};
1062
    ///
1063
    /// flags! {
1064
    ///     pub enum Flag: u8 {
1065
    ///         Foo = 1,
1066
    ///         Bar = 2,
1067
    ///         Baz = 4
1068
    ///     }
1069
    /// }
1070
    ///
1071
    /// let mut set = Flag::Foo | Flag::Bar;
1072
    /// let mut iter = set.drain();
1073
    /// assert!(set.is_empty());
1074
    /// assert_eq!(iter.next(), Some(Flag::Foo));
1075
    /// assert_eq!(iter.next(), Some(Flag::Bar));
1076
    /// assert_eq!(iter.next(), None);
1077
    /// ```
1078
    #[inline]
1079
    pub fn drain(&mut self) -> Iter<F> {
1080
        let iter = self.into_iter();
1081
        *self = Self::default();
1082
        iter
1083
    }
1084
1085
    /// Retain only the flags flags specified by the predicate.
1086
    ///
1087
    /// ```
1088
    /// use flagset::{FlagSet, flags};
1089
    ///
1090
    /// flags! {
1091
    ///     pub enum Flag: u8 {
1092
    ///         Foo = 1,
1093
    ///         Bar = 2,
1094
    ///         Baz = 4
1095
    ///     }
1096
    /// }
1097
    ///
1098
    /// let mut set0 = Flag::Foo | Flag::Bar;
1099
    /// set0.retain(|f| f != Flag::Foo);
1100
    /// assert_eq!(set0, Flag::Bar);
1101
    /// ```
1102
    #[inline]
1103
    pub fn retain(&mut self, func: impl Fn(F) -> bool) {
1104
        for f in self.into_iter() {
1105
            if !func(f) {
1106
                *self -= f
1107
            }
1108
        }
1109
    }
1110
}
1111
1112
#[cfg(feature = "serde")]
1113
impl<F: Flags> serde::Serialize for FlagSet<F>
1114
where
1115
    F::Type: serde::ser::Serialize,
1116
{
1117
    #[inline]
1118
    fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
1119
    where
1120
        S: serde::ser::Serializer,
1121
    {
1122
        self.0.serialize(serializer)
1123
    }
1124
}
1125
1126
#[cfg(feature = "serde")]
1127
impl<'de, F: Flags> serde::Deserialize<'de> for FlagSet<F>
1128
where
1129
    F::Type: serde::de::Deserialize<'de>,
1130
{
1131
    #[inline]
1132
    fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
1133
    where
1134
        D: serde::de::Deserializer<'de>,
1135
    {
1136
        Ok(FlagSet(F::Type::deserialize(deserializer)?))
1137
    }
1138
}
1139
1140
/// Define flag value using the `enum` syntax. See below for details.
1141
///
1142
/// Each enumeration value **MUST** have a specified value.
1143
///
1144
/// The width of the bitfield **MUST** also be specified by its integer type.
1145
///
1146
/// It is important to note that the size of the flag enumeration itself is
1147
/// unrelated to the size of the corresponding `FlagSet` instance.
1148
///
1149
/// It is also worth noting that this macro automatically implements a variety
1150
/// of standard traits including:
1151
///   * Copy
1152
///   * Clone
1153
///   * Debug
1154
///   * PartialEq
1155
///   * Eq
1156
///   * From<$enum> for $integer
1157
///   * Not
1158
///   * BitAnd
1159
///   * BitOr
1160
///   * BitXor
1161
///   * Sub
1162
///   * Rem
1163
///
1164
/// ```
1165
/// use std::mem::{align_of, size_of};
1166
/// use flagset::{FlagSet, flags};
1167
///
1168
/// flags! {
1169
///     enum FlagEmpty: u32 {}
1170
///
1171
///     enum Flag8: u8 {
1172
///         Foo = 0b001,
1173
///         Bar = 0b010,
1174
///         Baz = 0b100
1175
///     }
1176
///
1177
///     pub enum Flag16: u16 {
1178
///         Foo,
1179
///         Bar,
1180
///         #[deprecated]
1181
///         Baz,
1182
///     }
1183
///
1184
///     #[derive(PartialOrd, Ord)]
1185
///     enum Flag32: u32 {
1186
///         Foo = 0b001,
1187
///         #[deprecated]
1188
///         Bar = 0b010,
1189
///         Baz = 0b100
1190
///     }
1191
///
1192
///     #[repr(u64)]
1193
///     enum Flag64: u64 {
1194
///         Foo = 0b001,
1195
///         Bar = 0b010,
1196
///         Baz = 0b100
1197
///     }
1198
///
1199
///     #[repr(u32)]
1200
///     enum Flag128: u128 {
1201
///         Foo = 0b001,
1202
///         Bar = 0b010,
1203
///         Baz = 0b100
1204
///     }
1205
/// }
1206
///
1207
/// assert_eq!(size_of::<Flag8>(), 1);
1208
/// assert_eq!(size_of::<Flag16>(), 1);
1209
/// assert_eq!(size_of::<Flag32>(), 1);
1210
/// assert_eq!(size_of::<Flag64>(), 8);
1211
/// assert_eq!(size_of::<Flag128>(), 4);
1212
///
1213
/// assert_eq!(align_of::<Flag8>(), 1);
1214
/// assert_eq!(align_of::<Flag16>(), 1);
1215
/// assert_eq!(align_of::<Flag32>(), 1);
1216
/// assert_eq!(align_of::<Flag64>(), align_of::<u64>());
1217
/// assert_eq!(align_of::<Flag128>(), align_of::<u32>());
1218
///
1219
/// assert_eq!(size_of::<FlagSet<Flag8>>(), size_of::<u8>());
1220
/// assert_eq!(size_of::<FlagSet<Flag16>>(), size_of::<u16>());
1221
/// assert_eq!(size_of::<FlagSet<Flag32>>(), size_of::<u32>());
1222
/// assert_eq!(size_of::<FlagSet<Flag64>>(), size_of::<u64>());
1223
/// assert_eq!(size_of::<FlagSet<Flag128>>(), size_of::<u128>());
1224
///
1225
/// assert_eq!(align_of::<FlagSet<Flag8>>(), align_of::<u8>());
1226
/// assert_eq!(align_of::<FlagSet<Flag16>>(), align_of::<u16>());
1227
/// assert_eq!(align_of::<FlagSet<Flag32>>(), align_of::<u32>());
1228
/// assert_eq!(align_of::<FlagSet<Flag64>>(), align_of::<u64>());
1229
/// assert_eq!(align_of::<FlagSet<Flag128>>(), align_of::<u128>());
1230
/// ```
1231
#[macro_export]
1232
macro_rules! flags {
1233
    () => {};
1234
1235
    // Entry point for enumerations without values.
1236
    ($(#[$m:meta])* $p:vis enum $n:ident: $t:ty { $($(#[$a:meta])* $k:ident),+ $(,)* } $($next:tt)*) => {
1237
        $crate::flags! { $(#[$m])* $p enum $n: $t { $($(#[$a])* $k = (1 << $n::$k as $t)),+ } $($next)* }
1238
    };
1239
1240
    // Entrypoint for enumerations with values.
1241
    ($(#[$m:meta])* $p:vis enum $n:ident: $t:ty { $($(#[$a:meta])*$k:ident = $v:expr),* $(,)* } $($next:tt)*) => {
1242
        $(#[$m])*
1243
        #[derive(Copy, Clone, Debug, PartialEq, Eq)]
1244
        $p enum $n { $($(#[$a])* $k),* }
1245
1246
        impl $crate::Flags for $n {
1247
            type Type = $t;
1248
1249
            const LIST: &'static [Self] = &[$($n::$k),*];
1250
        }
1251
1252
        impl core::convert::From<$n> for $crate::FlagSet<$n> {
1253
            #[inline]
1254
2.56M
            fn from(value: $n) -> Self {
1255
2.56M
                unsafe {
1256
2.56M
                    match value {
1257
1.58M
                        $($n::$k => Self::new_unchecked($v)),*
1258
                    }
1259
                }
1260
2.56M
            }
1261
2.56M
        }
1262
2.56M
1263
2.56M
        impl core::ops::Not for $n {
1264
2.56M
            type Output = $crate::FlagSet<$n>;
1265
2.56M
1266
2.56M
            #[inline]
1267
2.56M
            fn not(self) -> Self::Output {
1268
0
                !$crate::FlagSet::from(self)
1269
0
            }
1270
        }
1271
1272
        impl<R: core::convert::Into<$crate::FlagSet<$n>>> core::ops::BitAnd<R> for $n {
1273
            type Output = $crate::FlagSet<$n>;
1274
1275
            #[inline]
1276
0
            fn bitand(self, rhs: R) -> Self::Output {
1277
0
                $crate::FlagSet::from(self) & rhs
1278
0
            }
1279
        }
1280
1281
        impl<R: core::convert::Into<$crate::FlagSet<$n>>> core::ops::BitOr<R> for $n {
1282
            type Output = $crate::FlagSet<$n>;
1283
1284
            #[inline]
1285
0
            fn bitor(self, rhs: R) -> Self::Output {
1286
0
                $crate::FlagSet::from(self) | rhs
1287
0
            }
1288
        }
1289
1290
        impl<R: core::convert::Into<$crate::FlagSet<$n>>> core::ops::BitXor<R> for $n {
1291
            type Output = $crate::FlagSet<$n>;
1292
1293
            #[inline]
1294
0
            fn bitxor(self, rhs: R) -> Self::Output {
1295
0
                $crate::FlagSet::from(self) ^ rhs
1296
0
            }
1297
        }
1298
1299
        impl<R: core::convert::Into<$crate::FlagSet<$n>>> core::ops::Sub<R> for $n {
1300
            type Output = $crate::FlagSet<$n>;
1301
1302
            #[inline]
1303
0
            fn sub(self, rhs: R) -> Self::Output {
1304
0
                $crate::FlagSet::from(self) - rhs
1305
0
            }
1306
        }
1307
1308
        impl<R: core::convert::Into<$crate::FlagSet<$n>>> core::ops::Rem<R> for $n {
1309
            type Output = $crate::FlagSet<$n>;
1310
1311
            #[inline]
1312
0
            fn rem(self, rhs: R) -> Self::Output {
1313
0
                $crate::FlagSet::from(self) % rhs
1314
0
            }
1315
        }
1316
1317
        $crate::flags! { $($next)* }
1318
    };
1319
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/leb128-0.2.5/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! Read and write DWARF's "Little Endian Base 128" (LEB128) variable length
2
//! integer encoding.
3
//!
4
//! The implementation is a direct translation of the psuedocode in the DWARF 4
5
//! standard's appendix C.
6
//!
7
//! Read and write signed integers:
8
//!
9
//! ```
10
//! use leb128;
11
//!
12
//! let mut buf = [0; 1024];
13
//!
14
//! // Write to anything that implements `std::io::Write`.
15
//! {
16
//!     let mut writable = &mut buf[..];
17
//!     leb128::write::signed(&mut writable, -12345).expect("Should write number");
18
//! }
19
//!
20
//! // Read from anything that implements `std::io::Read`.
21
//! let mut readable = &buf[..];
22
//! let val = leb128::read::signed(&mut readable).expect("Should read number");
23
//! assert_eq!(val, -12345);
24
//! ```
25
//!
26
//! Or read and write unsigned integers:
27
//!
28
//! ```
29
//! use leb128;
30
//!
31
//! let mut buf = [0; 1024];
32
//!
33
//! {
34
//!     let mut writable = &mut buf[..];
35
//!     leb128::write::unsigned(&mut writable, 98765).expect("Should write number");
36
//! }
37
//!
38
//! let mut readable = &buf[..];
39
//! let val = leb128::read::unsigned(&mut readable).expect("Should read number");
40
//! assert_eq!(val, 98765);
41
//! ```
42
43
#![deny(missing_docs)]
44
45
#[doc(hidden)]
46
pub const CONTINUATION_BIT: u8 = 1 << 7;
47
#[doc(hidden)]
48
pub const SIGN_BIT: u8 = 1 << 6;
49
50
#[doc(hidden)]
51
#[inline]
52
432k
pub fn low_bits_of_byte(byte: u8) -> u8 {
53
432k
    byte & !CONTINUATION_BIT
54
432k
}
_RNvCsj0UwMd2jWOb_6leb12816low_bits_of_byteCs5HNiFFfDLPG_6decode
Line
Count
Source
52
230k
pub fn low_bits_of_byte(byte: u8) -> u8 {
53
230k
    byte & !CONTINUATION_BIT
54
230k
}
_RNvCsj0UwMd2jWOb_6leb12816low_bits_of_byteCs5Pk8z11FdwQ_12wasm_encoder
Line
Count
Source
52
201k
pub fn low_bits_of_byte(byte: u8) -> u8 {
53
201k
    byte & !CONTINUATION_BIT
54
201k
}
55
56
#[doc(hidden)]
57
#[inline]
58
201k
pub fn low_bits_of_u64(val: u64) -> u8 {
59
201k
    let byte = val & (std::u8::MAX as u64);
60
201k
    low_bits_of_byte(byte as u8)
61
201k
}
62
63
/// A module for reading LEB128-encoded signed and unsigned integers.
64
pub mod read {
65
    use super::{low_bits_of_byte, CONTINUATION_BIT, SIGN_BIT};
66
    use std::fmt;
67
    use std::io;
68
69
    /// An error type for reading LEB128-encoded values.
70
    #[derive(Debug)]
71
    pub enum Error {
72
        /// There was an underlying IO error.
73
        IoError(io::Error),
74
        /// The number being read is larger than can be represented.
75
        Overflow,
76
    }
77
78
    impl From<io::Error> for Error {
79
0
        fn from(e: io::Error) -> Self {
80
0
            Error::IoError(e)
81
0
        }
Unexecuted instantiation: _RNvXNtCsj0UwMd2jWOb_6leb1284readNtB2_5ErrorINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtNtCs5s0IcynIBo_3std2io5error5ErrorE4fromCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvXNtCsj0UwMd2jWOb_6leb1284readNtB2_5ErrorINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtNtCs5s0IcynIBo_3std2io5error5ErrorE4fromCs5Pk8z11FdwQ_12wasm_encoder
82
    }
83
84
    impl fmt::Display for Error {
85
        fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
86
            match *self {
87
                Error::IoError(ref e) => e.fmt(f),
88
                Error::Overflow => {
89
                    write!(f, "The number being read is larger than can be represented")
90
                }
91
            }
92
        }
93
    }
94
95
    impl std::error::Error for Error {
96
        fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
97
            match *self {
98
                Error::IoError(ref e) => Some(e),
99
                Error::Overflow => None,
100
            }
101
        }
102
    }
103
104
    /// Read an unsigned LEB128-encoded number from the `std::io::Read` stream
105
    /// `r`.
106
    ///
107
    /// On success, return the number.
108
179k
    pub fn unsigned<R>(r: &mut R) -> Result<u64, Error>
109
179k
    where
110
179k
        R: ?Sized + io::Read,
111
179k
    {
112
179k
        let mut result = 0;
113
179k
        let mut shift = 0;
114
115
        loop {
116
187k
            let mut buf = [0];
117
187k
            r.read_exact(&mut buf)?;
118
119
187k
            if shift == 63 && buf[0] != 0x00 && buf[0] != 0x01 {
120
0
                while buf[0] & CONTINUATION_BIT != 0 {
121
0
                    r.read_exact(&mut buf)?;
122
                }
123
0
                return Err(Error::Overflow);
124
187k
            }
125
187k
126
187k
            let low_bits = low_bits_of_byte(buf[0]) as u64;
127
187k
            result |= low_bits << shift;
128
187k
129
187k
            if buf[0] & CONTINUATION_BIT == 0 {
130
179k
                return Ok(result);
131
8.56k
            }
132
8.56k
133
8.56k
            shift += 7;
134
        }
135
179k
    }
_RINvNtCsj0UwMd2jWOb_6leb1284read8unsignedINtNtNtNtCs5s0IcynIBo_3std2io8buffered9bufreader9BufReaderRShEECs5HNiFFfDLPG_6decode
Line
Count
Source
108
179k
    pub fn unsigned<R>(r: &mut R) -> Result<u64, Error>
109
179k
    where
110
179k
        R: ?Sized + io::Read,
111
179k
    {
112
179k
        let mut result = 0;
113
179k
        let mut shift = 0;
114
115
        loop {
116
187k
            let mut buf = [0];
117
187k
            r.read_exact(&mut buf)?;
118
119
187k
            if shift == 63 && buf[0] != 0x00 && buf[0] != 0x01 {
120
0
                while buf[0] & CONTINUATION_BIT != 0 {
121
0
                    r.read_exact(&mut buf)?;
122
                }
123
0
                return Err(Error::Overflow);
124
187k
            }
125
187k
126
187k
            let low_bits = low_bits_of_byte(buf[0]) as u64;
127
187k
            result |= low_bits << shift;
128
187k
129
187k
            if buf[0] & CONTINUATION_BIT == 0 {
130
179k
                return Ok(result);
131
8.56k
            }
132
8.56k
133
8.56k
            shift += 7;
134
        }
135
179k
    }
Unexecuted instantiation: _RINvNtCsj0UwMd2jWOb_6leb1284read8unsignedRShECs5Pk8z11FdwQ_12wasm_encoder
136
137
    /// Read a signed LEB128-encoded number from the `std::io::Read` stream `r`.
138
    ///
139
    /// On success, return the number.
140
11.5k
    pub fn signed<R>(r: &mut R) -> Result<i64, Error>
141
11.5k
    where
142
11.5k
        R: ?Sized + io::Read,
143
11.5k
    {
144
11.5k
        let mut result = 0;
145
11.5k
        let mut shift = 0;
146
11.5k
        let size = 64;
147
        let mut byte;
148
149
42.9k
        loop {
150
42.9k
            let mut buf = [0];
151
42.9k
            r.read_exact(&mut buf)?;
152
153
42.9k
            byte = buf[0];
154
42.9k
            if shift == 63 && byte != 0x00 && byte != 0x7f {
155
0
                while buf[0] & CONTINUATION_BIT != 0 {
156
0
                    r.read_exact(&mut buf)?;
157
                }
158
0
                return Err(Error::Overflow);
159
42.9k
            }
160
42.9k
161
42.9k
            let low_bits = low_bits_of_byte(byte) as i64;
162
42.9k
            result |= low_bits << shift;
163
42.9k
            shift += 7;
164
42.9k
165
42.9k
            if byte & CONTINUATION_BIT == 0 {
166
11.5k
                break;
167
31.4k
            }
168
        }
169
170
11.5k
        if shift < size && (SIGN_BIT & byte) == SIGN_BIT {
171
4.43k
            // Sign extend the result.
172
4.43k
            result |= !0 << shift;
173
7.11k
        }
174
175
11.5k
        Ok(result)
176
11.5k
    }
177
}
178
179
/// A module for writing LEB128-encoded signed and unsigned integers.
180
pub mod write {
181
    use super::{low_bits_of_u64, CONTINUATION_BIT};
182
    use std::io;
183
184
    /// Write `val` to the `std::io::Write` stream `w` as an unsigned LEB128 value.
185
    ///
186
    /// On success, return the number of bytes written to `w`.
187
193k
    pub fn unsigned<W>(w: &mut W, mut val: u64) -> Result<usize, io::Error>
188
193k
    where
189
193k
        W: ?Sized + io::Write,
190
193k
    {
191
193k
        let mut bytes_written = 0;
192
201k
        loop {
193
201k
            let mut byte = low_bits_of_u64(val);
194
201k
            val >>= 7;
195
201k
            if val != 0 {
196
8.56k
                // More bytes to come, so set the continuation bit.
197
8.56k
                byte |= CONTINUATION_BIT;
198
193k
            }
199
200
201k
            let buf = [byte];
201
201k
            w.write_all(&buf)?;
202
201k
            bytes_written += 1;
203
201k
204
201k
            if val == 0 {
205
193k
                return Ok(bytes_written);
206
8.56k
            }
207
        }
208
193k
    }
_RINvNtCsj0UwMd2jWOb_6leb1285write8unsignedINtNtCsbpSlAbJY2yh_5alloc3vec3VechEECs5Pk8z11FdwQ_12wasm_encoder
Line
Count
Source
187
171k
    pub fn unsigned<W>(w: &mut W, mut val: u64) -> Result<usize, io::Error>
188
171k
    where
189
171k
        W: ?Sized + io::Write,
190
171k
    {
191
171k
        let mut bytes_written = 0;
192
180k
        loop {
193
180k
            let mut byte = low_bits_of_u64(val);
194
180k
            val >>= 7;
195
180k
            if val != 0 {
196
8.56k
                // More bytes to come, so set the continuation bit.
197
8.56k
                byte |= CONTINUATION_BIT;
198
171k
            }
199
200
180k
            let buf = [byte];
201
180k
            w.write_all(&buf)?;
202
180k
            bytes_written += 1;
203
180k
204
180k
            if val == 0 {
205
171k
                return Ok(bytes_written);
206
8.56k
            }
207
        }
208
171k
    }
_RINvNtCsj0UwMd2jWOb_6leb1285write8unsignedQShECs5Pk8z11FdwQ_12wasm_encoder
Line
Count
Source
187
21.4k
    pub fn unsigned<W>(w: &mut W, mut val: u64) -> Result<usize, io::Error>
188
21.4k
    where
189
21.4k
        W: ?Sized + io::Write,
190
21.4k
    {
191
21.4k
        let mut bytes_written = 0;
192
21.4k
        loop {
193
21.4k
            let mut byte = low_bits_of_u64(val);
194
21.4k
            val >>= 7;
195
21.4k
            if val != 0 {
196
0
                // More bytes to come, so set the continuation bit.
197
0
                byte |= CONTINUATION_BIT;
198
21.4k
            }
199
200
21.4k
            let buf = [byte];
201
21.4k
            w.write_all(&buf)?;
202
21.4k
            bytes_written += 1;
203
21.4k
204
21.4k
            if val == 0 {
205
21.4k
                return Ok(bytes_written);
206
0
            }
207
        }
208
21.4k
    }
209
210
    /// Write `val` to the `std::io::Write` stream `w` as a signed LEB128 value.
211
    ///
212
    /// On success, return the number of bytes written to `w`.
213
13.4k
    pub fn signed<W>(w: &mut W, mut val: i64) -> Result<usize, io::Error>
214
13.4k
    where
215
13.4k
        W: ?Sized + io::Write,
216
13.4k
    {
217
13.4k
        let mut bytes_written = 0;
218
44.9k
        loop {
219
44.9k
            let mut byte = val as u8;
220
44.9k
            // Keep the sign bit for testing
221
44.9k
            val >>= 6;
222
44.9k
            let done = val == 0 || val == -1;
223
44.9k
            if done {
224
13.4k
                byte &= !CONTINUATION_BIT;
225
31.4k
            } else {
226
31.4k
                // Remove the sign bit
227
31.4k
                val >>= 1;
228
31.4k
                // More bytes to come, so set the continuation bit.
229
31.4k
                byte |= CONTINUATION_BIT;
230
31.4k
            }
231
232
44.9k
            let buf = [byte];
233
44.9k
            w.write_all(&buf)?;
234
44.9k
            bytes_written += 1;
235
44.9k
236
44.9k
            if done {
237
13.4k
                return Ok(bytes_written);
238
31.4k
            }
239
        }
240
13.4k
    }
241
}
242
243
#[cfg(test)]
244
mod tests {
245
    use super::*;
246
    use std;
247
    use std::io;
248
249
    #[test]
250
    fn test_low_bits_of_byte() {
251
        for i in 0..127 {
252
            assert_eq!(i, low_bits_of_byte(i));
253
            assert_eq!(i, low_bits_of_byte(i | CONTINUATION_BIT));
254
        }
255
    }
256
257
    #[test]
258
    fn test_low_bits_of_u64() {
259
        for i in 0u64..127 {
260
            assert_eq!(i as u8, low_bits_of_u64(1 << 16 | i));
261
            assert_eq!(
262
                i as u8,
263
                low_bits_of_u64(i << 16 | i | (CONTINUATION_BIT as u64))
264
            );
265
        }
266
    }
267
268
    // Examples from the DWARF 4 standard, section 7.6, figure 22.
269
    #[test]
270
    fn test_read_unsigned() {
271
        let buf = [2u8];
272
        let mut readable = &buf[..];
273
        assert_eq!(
274
            2,
275
            read::unsigned(&mut readable).expect("Should read number")
276
        );
277
278
        let buf = [127u8];
279
        let mut readable = &buf[..];
280
        assert_eq!(
281
            127,
282
            read::unsigned(&mut readable).expect("Should read number")
283
        );
284
285
        let buf = [CONTINUATION_BIT, 1];
286
        let mut readable = &buf[..];
287
        assert_eq!(
288
            128,
289
            read::unsigned(&mut readable).expect("Should read number")
290
        );
291
292
        let buf = [1u8 | CONTINUATION_BIT, 1];
293
        let mut readable = &buf[..];
294
        assert_eq!(
295
            129,
296
            read::unsigned(&mut readable).expect("Should read number")
297
        );
298
299
        let buf = [2u8 | CONTINUATION_BIT, 1];
300
        let mut readable = &buf[..];
301
        assert_eq!(
302
            130,
303
            read::unsigned(&mut readable).expect("Should read number")
304
        );
305
306
        let buf = [57u8 | CONTINUATION_BIT, 100];
307
        let mut readable = &buf[..];
308
        assert_eq!(
309
            12857,
310
            read::unsigned(&mut readable).expect("Should read number")
311
        );
312
    }
313
314
    #[test]
315
    fn test_read_unsigned_thru_dyn_trait() {
316
        fn read(r: &mut dyn io::Read) -> u64 {
317
            read::unsigned(r).expect("Should read number")
318
        }
319
320
        let buf = [0u8];
321
322
        let mut readable = &buf[..];
323
        assert_eq!(0, read(&mut readable));
324
325
        let mut readable = io::Cursor::new(buf);
326
        assert_eq!(0, read(&mut readable));
327
    }
328
329
    // Examples from the DWARF 4 standard, section 7.6, figure 23.
330
    #[test]
331
    fn test_read_signed() {
332
        let buf = [2u8];
333
        let mut readable = &buf[..];
334
        assert_eq!(2, read::signed(&mut readable).expect("Should read number"));
335
336
        let buf = [0x7eu8];
337
        let mut readable = &buf[..];
338
        assert_eq!(-2, read::signed(&mut readable).expect("Should read number"));
339
340
        let buf = [127u8 | CONTINUATION_BIT, 0];
341
        let mut readable = &buf[..];
342
        assert_eq!(
343
            127,
344
            read::signed(&mut readable).expect("Should read number")
345
        );
346
347
        let buf = [1u8 | CONTINUATION_BIT, 0x7f];
348
        let mut readable = &buf[..];
349
        assert_eq!(
350
            -127,
351
            read::signed(&mut readable).expect("Should read number")
352
        );
353
354
        let buf = [CONTINUATION_BIT, 1];
355
        let mut readable = &buf[..];
356
        assert_eq!(
357
            128,
358
            read::signed(&mut readable).expect("Should read number")
359
        );
360
361
        let buf = [CONTINUATION_BIT, 0x7f];
362
        let mut readable = &buf[..];
363
        assert_eq!(
364
            -128,
365
            read::signed(&mut readable).expect("Should read number")
366
        );
367
368
        let buf = [1u8 | CONTINUATION_BIT, 1];
369
        let mut readable = &buf[..];
370
        assert_eq!(
371
            129,
372
            read::signed(&mut readable).expect("Should read number")
373
        );
374
375
        let buf = [0x7fu8 | CONTINUATION_BIT, 0x7e];
376
        let mut readable = &buf[..];
377
        assert_eq!(
378
            -129,
379
            read::signed(&mut readable).expect("Should read number")
380
        );
381
    }
382
383
    #[test]
384
    fn test_read_signed_thru_dyn_trait() {
385
        fn read(r: &mut dyn io::Read) -> i64 {
386
            read::signed(r).expect("Should read number")
387
        }
388
389
        let buf = [0u8];
390
391
        let mut readable = &buf[..];
392
        assert_eq!(0, read(&mut readable));
393
394
        let mut readable = io::Cursor::new(buf);
395
        assert_eq!(0, read(&mut readable));
396
    }
397
398
    #[test]
399
    fn test_read_signed_63_bits() {
400
        let buf = [
401
            CONTINUATION_BIT,
402
            CONTINUATION_BIT,
403
            CONTINUATION_BIT,
404
            CONTINUATION_BIT,
405
            CONTINUATION_BIT,
406
            CONTINUATION_BIT,
407
            CONTINUATION_BIT,
408
            CONTINUATION_BIT,
409
            0x40,
410
        ];
411
        let mut readable = &buf[..];
412
        assert_eq!(
413
            -0x4000000000000000,
414
            read::signed(&mut readable).expect("Should read number")
415
        );
416
    }
417
418
    #[test]
419
    fn test_read_unsigned_not_enough_data() {
420
        let buf = [CONTINUATION_BIT];
421
        let mut readable = &buf[..];
422
        match read::unsigned(&mut readable) {
423
            Err(read::Error::IoError(e)) => assert_eq!(e.kind(), io::ErrorKind::UnexpectedEof),
424
            otherwise => panic!("Unexpected: {:?}", otherwise),
425
        }
426
    }
427
428
    #[test]
429
    fn test_read_signed_not_enough_data() {
430
        let buf = [CONTINUATION_BIT];
431
        let mut readable = &buf[..];
432
        match read::signed(&mut readable) {
433
            Err(read::Error::IoError(e)) => assert_eq!(e.kind(), io::ErrorKind::UnexpectedEof),
434
            otherwise => panic!("Unexpected: {:?}", otherwise),
435
        }
436
    }
437
438
    #[test]
439
    fn test_write_unsigned_not_enough_space() {
440
        let mut buf = [0; 1];
441
        let mut writable = &mut buf[..];
442
        match write::unsigned(&mut writable, 128) {
443
            Err(e) => assert_eq!(e.kind(), io::ErrorKind::WriteZero),
444
            otherwise => panic!("Unexpected: {:?}", otherwise),
445
        }
446
    }
447
448
    #[test]
449
    fn test_write_signed_not_enough_space() {
450
        let mut buf = [0; 1];
451
        let mut writable = &mut buf[..];
452
        match write::signed(&mut writable, 128) {
453
            Err(e) => assert_eq!(e.kind(), io::ErrorKind::WriteZero),
454
            otherwise => panic!("Unexpected: {:?}", otherwise),
455
        }
456
    }
457
458
    #[test]
459
    fn test_write_unsigned_thru_dyn_trait() {
460
        fn write(w: &mut dyn io::Write, val: u64) -> usize {
461
            write::unsigned(w, val).expect("Should write number")
462
        }
463
        let mut buf = [0u8; 1];
464
465
        let mut writable = &mut buf[..];
466
        assert_eq!(write(&mut writable, 0), 1);
467
        assert_eq!(buf[0], 0);
468
469
        let mut writable = Vec::from(&buf[..]);
470
        assert_eq!(write(&mut writable, 0), 1);
471
        assert_eq!(buf[0], 0);
472
    }
473
474
    #[test]
475
    fn test_write_signed_thru_dyn_trait() {
476
        fn write(w: &mut dyn io::Write, val: i64) -> usize {
477
            write::signed(w, val).expect("Should write number")
478
        }
479
        let mut buf = [0u8; 1];
480
481
        let mut writable = &mut buf[..];
482
        assert_eq!(write(&mut writable, 0), 1);
483
        assert_eq!(buf[0], 0);
484
485
        let mut writable = Vec::from(&buf[..]);
486
        assert_eq!(write(&mut writable, 0), 1);
487
        assert_eq!(buf[0], 0);
488
    }
489
490
    #[test]
491
    fn dogfood_signed() {
492
        fn inner(i: i64) {
493
            let mut buf = [0u8; 1024];
494
495
            {
496
                let mut writable = &mut buf[..];
497
                write::signed(&mut writable, i).expect("Should write signed number");
498
            }
499
500
            let mut readable = &buf[..];
501
            let result = read::signed(&mut readable).expect("Should be able to read it back again");
502
            assert_eq!(i, result);
503
        }
504
        for i in -513..513 {
505
            inner(i);
506
        }
507
        inner(std::i64::MIN);
508
    }
509
510
    #[test]
511
    fn dogfood_unsigned() {
512
        for i in 0..1025 {
513
            let mut buf = [0u8; 1024];
514
515
            {
516
                let mut writable = &mut buf[..];
517
                write::unsigned(&mut writable, i).expect("Should write signed number");
518
            }
519
520
            let mut readable = &buf[..];
521
            let result =
522
                read::unsigned(&mut readable).expect("Should be able to read it back again");
523
            assert_eq!(i, result);
524
        }
525
    }
526
527
    #[test]
528
    fn test_read_unsigned_overflow() {
529
        let buf = [
530
            2u8 | CONTINUATION_BIT,
531
            2 | CONTINUATION_BIT,
532
            2 | CONTINUATION_BIT,
533
            2 | CONTINUATION_BIT,
534
            2 | CONTINUATION_BIT,
535
            2 | CONTINUATION_BIT,
536
            2 | CONTINUATION_BIT,
537
            2 | CONTINUATION_BIT,
538
            2 | CONTINUATION_BIT,
539
            2 | CONTINUATION_BIT,
540
            2 | CONTINUATION_BIT,
541
            2 | CONTINUATION_BIT,
542
            2 | CONTINUATION_BIT,
543
            2 | CONTINUATION_BIT,
544
            2 | CONTINUATION_BIT,
545
            2 | CONTINUATION_BIT,
546
            2 | CONTINUATION_BIT,
547
            2 | CONTINUATION_BIT,
548
            2 | CONTINUATION_BIT,
549
            2 | CONTINUATION_BIT,
550
            2 | CONTINUATION_BIT,
551
            2 | CONTINUATION_BIT,
552
            2 | CONTINUATION_BIT,
553
            2 | CONTINUATION_BIT,
554
            2 | CONTINUATION_BIT,
555
            2 | CONTINUATION_BIT,
556
            2 | CONTINUATION_BIT,
557
            2 | CONTINUATION_BIT,
558
            2 | CONTINUATION_BIT,
559
            2 | CONTINUATION_BIT,
560
            1,
561
        ];
562
        let mut readable = &buf[..];
563
        assert!(read::unsigned(&mut readable).is_err());
564
    }
565
566
    #[test]
567
    fn test_read_signed_overflow() {
568
        let buf = [
569
            2u8 | CONTINUATION_BIT,
570
            2 | CONTINUATION_BIT,
571
            2 | CONTINUATION_BIT,
572
            2 | CONTINUATION_BIT,
573
            2 | CONTINUATION_BIT,
574
            2 | CONTINUATION_BIT,
575
            2 | CONTINUATION_BIT,
576
            2 | CONTINUATION_BIT,
577
            2 | CONTINUATION_BIT,
578
            2 | CONTINUATION_BIT,
579
            2 | CONTINUATION_BIT,
580
            2 | CONTINUATION_BIT,
581
            2 | CONTINUATION_BIT,
582
            2 | CONTINUATION_BIT,
583
            2 | CONTINUATION_BIT,
584
            2 | CONTINUATION_BIT,
585
            2 | CONTINUATION_BIT,
586
            2 | CONTINUATION_BIT,
587
            2 | CONTINUATION_BIT,
588
            2 | CONTINUATION_BIT,
589
            2 | CONTINUATION_BIT,
590
            2 | CONTINUATION_BIT,
591
            2 | CONTINUATION_BIT,
592
            2 | CONTINUATION_BIT,
593
            2 | CONTINUATION_BIT,
594
            2 | CONTINUATION_BIT,
595
            2 | CONTINUATION_BIT,
596
            2 | CONTINUATION_BIT,
597
            2 | CONTINUATION_BIT,
598
            2 | CONTINUATION_BIT,
599
            1,
600
        ];
601
        let mut readable = &buf[..];
602
        assert!(read::signed(&mut readable).is_err());
603
    }
604
605
    #[test]
606
    fn test_read_multiple() {
607
        let buf = [2u8 | CONTINUATION_BIT, 1u8, 1u8];
608
609
        let mut readable = &buf[..];
610
        assert_eq!(
611
            read::unsigned(&mut readable).expect("Should read first number"),
612
            130u64
613
        );
614
        assert_eq!(
615
            read::unsigned(&mut readable).expect("Should read first number"),
616
            1u64
617
        );
618
    }
619
620
    #[test]
621
    fn test_read_multiple_with_overflow() {
622
        let buf = [
623
            0b1111_1111,
624
            0b1111_1111,
625
            0b1111_1111,
626
            0b1111_1111,
627
            0b1111_1111,
628
            0b1111_1111,
629
            0b1111_1111,
630
            0b1111_1111,
631
            0b1111_1111,
632
            0b1111_1111,
633
            0b0111_1111, // Overflow!
634
            0b1110_0100,
635
            0b1110_0000,
636
            0b0000_0010, // 45156
637
        ];
638
        let mut readable = &buf[..];
639
640
        assert!(if let read::Error::Overflow =
641
            read::unsigned(&mut readable).expect_err("Should fail with Error::Overflow")
642
        {
643
            true
644
        } else {
645
            false
646
        });
647
        assert_eq!(
648
            read::unsigned(&mut readable).expect("Should succeed with correct value"),
649
            45156
650
        );
651
    }
652
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libfuzzer-sys-0.4.7/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! Bindings to [libFuzzer](http://llvm.org/docs/LibFuzzer.html): a runtime for
2
//! coverage-guided fuzzing.
3
//!
4
//! See [the `cargo-fuzz`
5
//! guide](https://rust-fuzz.github.io/book/cargo-fuzz.html) for a usage
6
//! tutorial.
7
//!
8
//! The main export of this crate is [the `fuzz_target!`
9
//! macro](./macro.fuzz_target.html), which allows you to define targets for
10
//! libFuzzer to exercise.
11
12
#![deny(missing_docs, missing_debug_implementations)]
13
14
pub use arbitrary;
15
use once_cell::sync::OnceCell;
16
17
/// Indicates whether the input should be kept in the corpus or rejected. This
18
/// should be returned by your fuzz target. If your fuzz target does not return
19
/// a value (i.e., returns `()`), then the input will be kept in the corpus.
20
#[derive(Debug)]
21
pub enum Corpus {
22
    /// Keep the input in the corpus.
23
    Keep,
24
25
    /// Reject the input and do not keep it in the corpus.
26
    Reject,
27
}
28
29
impl From<()> for Corpus {
30
5.67k
    fn from(_: ()) -> Self {
31
5.67k
        Self::Keep
32
5.67k
    }
_RNvXCs32fhybPB127_13libfuzzer_sysNtB2_6CorpusINtNtCs1ujR1JRCAmI_4core7convert4FromuE4fromCs5HNiFFfDLPG_6decode
Line
Count
Source
30
5.67k
    fn from(_: ()) -> Self {
31
5.67k
        Self::Keep
32
5.67k
    }
Unexecuted instantiation: _RNvXCs32fhybPB127_13libfuzzer_sysNtB2_6CorpusINtNtCs1ujR1JRCAmI_4core7convert4FromuE4fromB2_
33
}
34
35
impl Corpus {
36
    #[doc(hidden)]
37
    /// Convert this Corpus result into the [integer codes used by
38
    /// `libFuzzer`](https://llvm.org/docs/LibFuzzer.html#rejecting-unwanted-inputs).
39
    /// This is -1 for reject, 0 for keep.
40
5.67k
    pub fn to_libfuzzer_code(self) -> i32 {
41
5.67k
        match self {
42
5.67k
            Corpus::Keep => 0,
43
0
            Corpus::Reject => -1,
44
        }
45
5.67k
    }
_RNvMs_Cs32fhybPB127_13libfuzzer_sysNtB4_6Corpus17to_libfuzzer_codeCs5HNiFFfDLPG_6decode
Line
Count
Source
40
5.67k
    pub fn to_libfuzzer_code(self) -> i32 {
41
5.67k
        match self {
42
5.67k
            Corpus::Keep => 0,
43
0
            Corpus::Reject => -1,
44
        }
45
5.67k
    }
Unexecuted instantiation: _RNvMs_Cs32fhybPB127_13libfuzzer_sysNtB4_6Corpus17to_libfuzzer_codeB4_
46
}
47
48
extern "C" {
49
    // We do not actually cross the FFI bound here.
50
    #[allow(improper_ctypes)]
51
    fn rust_fuzzer_test_input(input: &[u8]) -> i32;
52
53
    fn LLVMFuzzerMutate(data: *mut u8, size: usize, max_size: usize) -> usize;
54
}
55
56
#[doc(hidden)]
57
#[export_name = "LLVMFuzzerTestOneInput"]
58
5.67k
pub fn test_input_wrap(data: *const u8, size: usize) -> i32 {
59
5.67k
    let test_input = ::std::panic::catch_unwind(|| unsafe {
60
5.67k
        let data_slice = ::std::slice::from_raw_parts(data, size);
61
5.67k
        rust_fuzzer_test_input(data_slice)
62
5.67k
    });
63
5.67k
64
5.67k
    match test_input {
65
5.67k
        Ok(i) => i,
66
        Err(_) => {
67
            // hopefully the custom panic hook will be called before and abort the
68
            // process before the stack frames are unwinded.
69
0
            ::std::process::abort();
70
        }
71
    }
72
5.67k
}
73
74
#[doc(hidden)]
75
pub static RUST_LIBFUZZER_DEBUG_PATH: OnceCell<String> = OnceCell::new();
76
77
#[doc(hidden)]
78
#[export_name = "LLVMFuzzerInitialize"]
79
2
pub fn initialize(_argc: *const isize, _argv: *const *const *const u8) -> isize {
80
2
    // Registers a panic hook that aborts the process before unwinding.
81
2
    // It is useful to abort before unwinding so that the fuzzer will then be
82
2
    // able to analyse the process stack frames to tell different bugs appart.
83
2
    //
84
2
    // HACK / FIXME: it would be better to use `-C panic=abort` but it's currently
85
2
    // impossible to build code using compiler plugins with this flag.
86
2
    // We will be able to remove this code when
87
2
    // https://github.com/rust-lang/cargo/issues/5423 is fixed.
88
2
    let default_hook = ::std::panic::take_hook();
89
2
    ::std::panic::set_hook(Box::new(move |panic_info| {
90
0
        default_hook(panic_info);
91
0
        ::std::process::abort();
92
2
    }));
93
94
    // Initialize the `RUST_LIBFUZZER_DEBUG_PATH` cell with the path so it can be
95
    // reused with little overhead.
96
2
    if let Ok(path) = std::env::var("RUST_LIBFUZZER_DEBUG_PATH") {
97
0
        RUST_LIBFUZZER_DEBUG_PATH
98
0
            .set(path)
99
0
            .expect("Since this is initialize it is only called once so can never fail");
100
2
    }
101
2
    0
102
2
}
103
104
/// Define a fuzz target.
105
///
106
/// ## Example
107
///
108
/// This example takes a `&[u8]` slice and attempts to parse it. The parsing
109
/// might fail and return an `Err`, but it shouldn't ever panic or segfault.
110
///
111
/// ```no_run
112
/// #![no_main]
113
///
114
/// use libfuzzer_sys::fuzz_target;
115
///
116
/// // Note: `|input|` is short for `|input: &[u8]|`.
117
/// fuzz_target!(|input| {
118
///     let _result: Result<_, _> = my_crate::parse(input);
119
/// });
120
/// # mod my_crate { pub fn parse(_: &[u8]) -> Result<(), ()> { unimplemented!() } }
121
/// ```
122
///
123
/// ## Rejecting Inputs
124
///
125
/// It may be desirable to reject some inputs, i.e. to not add them to the
126
/// corpus.
127
///
128
/// For example, when fuzzing an API consisting of parsing and other logic,
129
/// one may want to allow only those inputs into the corpus that parse
130
/// successfully. To indicate whether an input should be kept in or rejected
131
/// from the corpus, return either [Corpus::Keep] or [Corpus::Reject] from your
132
/// fuzz target. The default behavior (e.g. if `()` is returned) is to keep the
133
/// input in the corpus.
134
///
135
/// For example:
136
///
137
/// ```no_run
138
/// #![no_main]
139
///
140
/// use libfuzzer_sys::{Corpus, fuzz_target};
141
///
142
/// fuzz_target!(|input: String| -> Corpus {
143
///     let parts: Vec<&str> = input.splitn(2, '=').collect();
144
///     if parts.len() != 2 {
145
///         return Corpus::Reject;
146
///     }
147
///
148
///     let key = parts[0];
149
///     let value = parts[1];
150
///     let _result: Result<_, _> = my_crate::parse(key, value);
151
///     Corpus::Keep
152
/// });
153
/// # mod my_crate { pub fn parse(_key: &str, _value: &str) -> Result<(), ()> { unimplemented!() } }
154
/// ```
155
///
156
/// ## Arbitrary Input Types
157
///
158
/// The input is a `&[u8]` slice by default, but you can take arbitrary input
159
/// types, as long as the type implements [the `arbitrary` crate's `Arbitrary`
160
/// trait](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html) (which is
161
/// also re-exported as `libfuzzer_sys::arbitrary::Arbitrary` for convenience).
162
///
163
/// For example, if you wanted to take an arbitrary RGB color, you could do the
164
/// following:
165
///
166
/// ```no_run
167
/// #![no_main]
168
/// # mod foo {
169
///
170
/// use libfuzzer_sys::{arbitrary::{Arbitrary, Error, Unstructured}, fuzz_target};
171
///
172
/// #[derive(Debug)]
173
/// pub struct Rgb {
174
///     r: u8,
175
///     g: u8,
176
///     b: u8,
177
/// }
178
///
179
/// impl<'a> Arbitrary<'a> for Rgb {
180
///     fn arbitrary(raw: &mut Unstructured<'a>) -> Result<Self, Error> {
181
///         let mut buf = [0; 3];
182
///         raw.fill_buffer(&mut buf)?;
183
///         let r = buf[0];
184
///         let g = buf[1];
185
///         let b = buf[2];
186
///         Ok(Rgb { r, g, b })
187
///     }
188
/// }
189
///
190
/// // Write a fuzz target that works with RGB colors instead of raw bytes.
191
/// fuzz_target!(|color: Rgb| {
192
///     my_crate::convert_color(color);
193
/// });
194
/// # mod my_crate {
195
/// #     use super::Rgb;
196
/// #     pub fn convert_color(_: Rgb) {}
197
/// # }
198
/// # }
199
/// ```
200
///
201
/// You can also enable the `arbitrary` crate's custom derive via this crate's
202
/// `"arbitrary-derive"` cargo feature.
203
#[macro_export]
204
macro_rules! fuzz_target {
205
    (|$bytes:ident| $body:expr) => {
206
        const _: () = {
207
            /// Auto-generated function
208
            #[no_mangle]
209
            pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) -> i32 {
210
                // When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug
211
                // formatting of the input to that file. This is only intended for
212
                // `cargo fuzz`'s use!
213
214
                // `RUST_LIBFUZZER_DEBUG_PATH` is set in initialization.
215
                if let Some(path) = $crate::RUST_LIBFUZZER_DEBUG_PATH.get() {
216
                    use std::io::Write;
217
                    let mut file = std::fs::File::create(path)
218
                        .expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file");
219
                    writeln!(&mut file, "{:?}", bytes)
220
                        .expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file");
221
                    return 0;
222
                }
223
224
                __libfuzzer_sys_run(bytes);
225
                0
226
            }
227
228
            // Split out the actual fuzzer into a separate function which is
229
            // tagged as never being inlined. This ensures that if the fuzzer
230
            // panics there's at least one stack frame which is named uniquely
231
            // according to this specific fuzzer that this is embedded within.
232
            //
233
            // Systems like oss-fuzz try to deduplicate crashes and without this
234
            // panics in separate fuzzers can accidentally appear the same
235
            // because each fuzzer will have a function called
236
            // `rust_fuzzer_test_input`. By using a normal Rust function here
237
            // it's named something like `the_fuzzer_name::_::__libfuzzer_sys_run` which should
238
            // ideally help prevent oss-fuzz from deduplicate fuzz bugs across
239
            // distinct targets accidentally.
240
            #[inline(never)]
241
            fn __libfuzzer_sys_run($bytes: &[u8]) {
242
                $body
243
            }
244
        };
245
    };
246
247
    (|$data:ident: &[u8]| $body:expr) => {
248
        $crate::fuzz_target!(|$data| $body);
249
    };
250
251
    (|$data:ident: $dty:ty| $body:expr) => {
252
        $crate::fuzz_target!(|$data: $dty| -> () { $body });
253
    };
254
255
    (|$data:ident: $dty:ty| -> $rty:ty $body:block) => {
256
        const _: () = {
257
            /// Auto-generated function
258
            #[no_mangle]
259
5.67k
            pub extern "C" fn rust_fuzzer_test_input(bytes: &[u8]) -> i32 {
260
5.67k
                use $crate::arbitrary::{Arbitrary, Unstructured};
261
5.67k
262
5.67k
                // Early exit if we don't have enough bytes for the `Arbitrary`
263
5.67k
                // implementation. This helps the fuzzer avoid exploring all the
264
5.67k
                // different not-enough-input-bytes paths inside the `Arbitrary`
265
5.67k
                // implementation. Additionally, it exits faster, letting the fuzzer
266
5.67k
                // get to longer inputs that actually lead to interesting executions
267
5.67k
                // quicker.
268
5.67k
                if bytes.len() < <$dty as Arbitrary>::size_hint(0).0 {
269
0
                    return -1;
270
5.67k
                }
271
5.67k
272
5.67k
                let mut u = Unstructured::new(bytes);
273
5.67k
                let data = <$dty as Arbitrary>::arbitrary_take_rest(u);
274
275
                // When `RUST_LIBFUZZER_DEBUG_PATH` is set, write the debug
276
                // formatting of the input to that file. This is only intended for
277
                // `cargo fuzz`'s use!
278
279
                // `RUST_LIBFUZZER_DEBUG_PATH` is set in initialization.
280
5.67k
                if let Some(path) = $crate::RUST_LIBFUZZER_DEBUG_PATH.get() {
281
                    use std::io::Write;
282
0
                    let mut file = std::fs::File::create(path)
283
0
                        .expect("failed to create `RUST_LIBFUZZER_DEBUG_PATH` file");
284
0
                    (match data {
285
0
                        Ok(data) => writeln!(&mut file, "{:#?}", data),
286
0
                        Err(err) => writeln!(&mut file, "Arbitrary Error: {}", err),
287
                    })
288
0
                    .expect("failed to write to `RUST_LIBFUZZER_DEBUG_PATH` file");
289
0
                    return -1;
290
5.67k
                }
291
5.67k
292
5.67k
                let data = match data {
293
5.67k
                    Ok(d) => d,
294
0
                    Err(_) => return -1,
295
                };
296
297
5.67k
                let result = ::libfuzzer_sys::Corpus::from(__libfuzzer_sys_run(data));
298
5.67k
                result.to_libfuzzer_code()
299
5.67k
            }
300
5.67k
301
5.67k
            // See above for why this is split to a separate function.
302
5.67k
            #[inline(never)]
303
5.67k
            fn __libfuzzer_sys_run($data: $dty) -> $rty {
304
5.67k
                $body
305
5.67k
            }
306
        };
307
    };
308
}
309
310
/// Define a custom mutator.
311
///
312
/// This is optional, and libFuzzer will use its own, default mutation strategy
313
/// if this is not provided.
314
///
315
/// You might consider using a custom mutator when your fuzz target is very
316
/// particular about the shape of its input:
317
///
318
/// * You want to fuzz "deeper" than just the parser.
319
/// * The input contains checksums that have to match the hash of some subset of
320
///   the data or else the whole thing is invalid, and therefore mutating any of
321
///   that subset means you need to recompute the checksums.
322
/// * Small random changes to the input buffer make it invalid.
323
///
324
/// That is, a custom mutator is useful in similar situations where [a `T:
325
/// Arbitrary` input type](macro.fuzz_target.html#arbitrary-input-types) is
326
/// useful. Note that the two approaches are not mutually exclusive; you can use
327
/// whichever is easier for your problem domain or both!
328
///
329
/// ## Implementation Contract
330
///
331
/// The original, unmodified input is given in `data[..size]`.
332
///
333
/// You must modify the data in place and return the new size.
334
///
335
/// The new size should not be greater than `max_size`. If this is not the case,
336
/// then the `data` will be truncated to fit within `max_size`. Note that
337
/// `max_size < size` is possible when shrinking test cases.
338
///
339
/// You must produce the same mutation given the same `seed`. Generally, when
340
/// choosing what kind of mutation to make or where to mutate, you should start
341
/// by creating a random number generator (RNG) that is seeded with the given
342
/// `seed` and then consult the RNG whenever making a decision:
343
///
344
/// ```no_run
345
/// #![no_main]
346
///
347
/// use rand::{rngs::StdRng, Rng, SeedableRng};
348
///
349
/// libfuzzer_sys::fuzz_mutator!(|data: &mut [u8], size: usize, max_size: usize, seed: u32| {
350
///     let mut rng = StdRng::seed_from_u64(seed as u64);
351
///
352
/// #   let first_mutation = |_, _, _, _| todo!();
353
/// #   let second_mutation = |_, _, _, _| todo!();
354
/// #   let third_mutation = |_, _, _, _| todo!();
355
/// #   let fourth_mutation = |_, _, _, _| todo!();
356
///     // Choose which of our four supported kinds of mutations we want to make.
357
///     match rng.gen_range(0..4) {
358
///         0 => first_mutation(rng, data, size, max_size),
359
///         1 => second_mutation(rng, data, size, max_size),
360
///         2 => third_mutation(rng, data, size, max_size),
361
///         3 => fourth_mutation(rng, data, size, max_size),
362
///         _ => unreachable!()
363
///     }
364
/// });
365
/// ```
366
///
367
/// ## Example: Compression
368
///
369
/// Consider a simple fuzz target that takes compressed data as input,
370
/// decompresses it, and then asserts that the decompressed data doesn't begin
371
/// with "boom". It is difficult for `libFuzzer` (or any other fuzzer) to crash
372
/// this fuzz target because nearly all mutations it makes will invalidate the
373
/// compression format. Therefore, we use a custom mutator that decompresses the
374
/// raw input, mutates the decompressed data, and then recompresses it. This
375
/// allows `libFuzzer` to quickly discover crashing inputs.
376
///
377
/// ```no_run
378
/// #![no_main]
379
///
380
/// use flate2::{read::GzDecoder, write::GzEncoder, Compression};
381
/// use libfuzzer_sys::{fuzz_mutator, fuzz_target};
382
/// use std::io::{Read, Write};
383
///
384
/// fuzz_target!(|data: &[u8]| {
385
///     // Decompress the input data and crash if it starts with "boom".
386
///     if let Some(data) = decompress(data) {
387
///         if data.starts_with(b"boom") {
388
///             panic!();
389
///         }
390
///     }
391
/// });
392
///
393
/// fuzz_mutator!(
394
///     |data: &mut [u8], size: usize, max_size: usize, _seed: u32| {
395
///         // Decompress the input data. If that fails, use a dummy value.
396
///         let mut decompressed = decompress(&data[..size]).unwrap_or_else(|| b"hi".to_vec());
397
///
398
///         // Mutate the decompressed data with `libFuzzer`'s default mutator. Make
399
///         // the `decompressed` vec's extra capacity available for insertion
400
///         // mutations via `resize`.
401
///         let len = decompressed.len();
402
///         let cap = decompressed.capacity();
403
///         decompressed.resize(cap, 0);
404
///         let new_decompressed_size = libfuzzer_sys::fuzzer_mutate(&mut decompressed, len, cap);
405
///
406
///         // Recompress the mutated data.
407
///         let compressed = compress(&decompressed[..new_decompressed_size]);
408
///
409
///         // Copy the recompressed mutated data into `data` and return the new size.
410
///         let new_size = std::cmp::min(max_size, compressed.len());
411
///         data[..new_size].copy_from_slice(&compressed[..new_size]);
412
///         new_size
413
///     }
414
/// );
415
///
416
/// fn decompress(compressed_data: &[u8]) -> Option<Vec<u8>> {
417
///     let mut decoder = GzDecoder::new(compressed_data);
418
///     let mut decompressed = Vec::new();
419
///     if decoder.read_to_end(&mut decompressed).is_ok() {
420
///         Some(decompressed)
421
///     } else {
422
///         None
423
///     }
424
/// }
425
///
426
/// fn compress(data: &[u8]) -> Vec<u8> {
427
///     let mut encoder = GzEncoder::new(Vec::new(), Compression::default());
428
///     encoder
429
///         .write_all(data)
430
///         .expect("writing into a vec is infallible");
431
///     encoder.finish().expect("writing into a vec is infallible")
432
/// }
433
/// ```
434
///
435
/// This example is inspired by [a similar example from the official `libFuzzer`
436
/// docs](https://github.com/google/fuzzing/blob/master/docs/structure-aware-fuzzing.md#example-compression).
437
///
438
/// ## More Example Ideas
439
///
440
/// * A PNG custom mutator that decodes a PNG, mutates the image, and then
441
/// re-encodes the mutated image as a new PNG.
442
///
443
/// * A [`serde`](https://serde.rs/) custom mutator that deserializes your
444
///   structure, mutates it, and then reserializes it.
445
///
446
/// * A Wasm binary custom mutator that inserts, replaces, and removes a
447
///   bytecode instruction in a function's body.
448
///
449
/// * An HTTP request custom mutator that inserts, replaces, and removes a
450
///   header from an HTTP request.
451
#[macro_export]
452
macro_rules! fuzz_mutator {
453
    (
454
        |
455
        $data:ident : &mut [u8] ,
456
        $size:ident : usize ,
457
        $max_size:ident : usize ,
458
        $seed:ident : u32 $(,)*
459
        |
460
        $body:block
461
    ) => {
462
        /// Auto-generated function.
463
        #[export_name = "LLVMFuzzerCustomMutator"]
464
        pub fn rust_fuzzer_custom_mutator(
465
            $data: *mut u8,
466
            $size: usize,
467
            $max_size: usize,
468
            $seed: std::os::raw::c_uint,
469
        ) -> usize {
470
            // Depending on if we are growing or shrinking the test case, `size`
471
            // might be larger or smaller than `max_size`. The `data`'s capacity
472
            // is the maximum of the two.
473
            let len = std::cmp::max($max_size, $size);
474
            let $data: &mut [u8] = unsafe { std::slice::from_raw_parts_mut($data, len) };
475
476
            // `unsigned int` is generally a `u32`, but not on all targets. Do
477
            // an infallible (and potentially lossy, but that's okay because it
478
            // preserves determinism) conversion.
479
            let $seed = $seed as u32;
480
481
            // Truncate the new size if it is larger than the max.
482
            let new_size = { $body };
483
            std::cmp::min(new_size, $max_size)
484
        }
485
    };
486
}
487
488
/// The default `libFuzzer` mutator.
489
///
490
/// You generally don't have to use this at all unless you're defining a
491
/// custom mutator with [the `fuzz_mutator!` macro][crate::fuzz_mutator].
492
///
493
/// Mutates `data[..size]` in place such that the mutated data is no larger than
494
/// `max_size` and returns the new size of the mutated data.
495
///
496
/// To only allow shrinking mutations, make `max_size < size`.
497
///
498
/// To additionally allow mutations that grow the size of the data, make
499
/// `max_size > size`.
500
///
501
/// Both `size` and `max_size` must be less than or equal to `data.len()`.
502
///
503
/// # Example
504
///
505
/// ```no_run
506
/// // Create some data in a buffer.
507
/// let mut data = vec![0; 128];
508
/// data[..b"hello".len()].copy_from_slice(b"hello");
509
///
510
/// // Ask `libFuzzer` to mutate the data. By setting `max_size` to our buffer's
511
/// // full length, we are allowing `libFuzzer` to perform mutations that grow
512
/// // the size of the data, such as insertions.
513
/// let size = b"hello".len();
514
/// let max_size = data.len();
515
/// let new_size = libfuzzer_sys::fuzzer_mutate(&mut data, size, max_size);
516
///
517
/// // Get the mutated data out of the buffer.
518
/// let mutated_data = &data[..new_size];
519
/// ```
520
0
pub fn fuzzer_mutate(data: &mut [u8], size: usize, max_size: usize) -> usize {
521
0
    assert!(size <= data.len());
522
0
    assert!(max_size <= data.len());
523
0
    let new_size = unsafe { LLVMFuzzerMutate(data.as_mut_ptr(), size, max_size) };
524
0
    assert!(new_size <= data.len());
525
0
    new_size
526
0
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.19.0/src/imp_std.rs
Line
Count
Source (jump to first uncovered line)
1
// There's a lot of scary concurrent code in this module, but it is copied from
2
// `std::sync::Once` with two changes:
3
//   * no poisoning
4
//   * init function can fail
5
6
use std::{
7
    cell::{Cell, UnsafeCell},
8
    panic::{RefUnwindSafe, UnwindSafe},
9
    sync::atomic::{AtomicBool, AtomicPtr, Ordering},
10
    thread::{self, Thread},
11
};
12
13
#[derive(Debug)]
14
pub(crate) struct OnceCell<T> {
15
    // This `queue` field is the core of the implementation. It encodes two
16
    // pieces of information:
17
    //
18
    // * The current state of the cell (`INCOMPLETE`, `RUNNING`, `COMPLETE`)
19
    // * Linked list of threads waiting for the current cell.
20
    //
21
    // State is encoded in two low bits. Only `INCOMPLETE` and `RUNNING` states
22
    // allow waiters.
23
    queue: AtomicPtr<Waiter>,
24
    value: UnsafeCell<Option<T>>,
25
}
26
27
// Why do we need `T: Send`?
28
// Thread A creates a `OnceCell` and shares it with
29
// scoped thread B, which fills the cell, which is
30
// then destroyed by A. That is, destructor observes
31
// a sent value.
32
unsafe impl<T: Sync + Send> Sync for OnceCell<T> {}
33
unsafe impl<T: Send> Send for OnceCell<T> {}
34
35
impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
36
impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
37
38
impl<T> OnceCell<T> {
39
0
    pub(crate) const fn new() -> OnceCell<T> {
40
0
        OnceCell { queue: AtomicPtr::new(INCOMPLETE_PTR), value: UnsafeCell::new(None) }
41
0
    }
42
43
0
    pub(crate) const fn with_value(value: T) -> OnceCell<T> {
44
0
        OnceCell { queue: AtomicPtr::new(COMPLETE_PTR), value: UnsafeCell::new(Some(value)) }
45
0
    }
46
47
    /// Safety: synchronizes with store to value via Release/(Acquire|SeqCst).
48
    #[inline]
49
5.67k
    pub(crate) fn is_initialized(&self) -> bool {
50
5.67k
        // An `Acquire` load is enough because that makes all the initialization
51
5.67k
        // operations visible to us, and, this being a fast path, weaker
52
5.67k
        // ordering helps with performance. This `Acquire` synchronizes with
53
5.67k
        // `SeqCst` operations on the slow path.
54
5.67k
        self.queue.load(Ordering::Acquire) == COMPLETE_PTR
55
5.67k
    }
_RNvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE14is_initializedCs5HNiFFfDLPG_6decode
Line
Count
Source
49
5.67k
    pub(crate) fn is_initialized(&self) -> bool {
50
5.67k
        // An `Acquire` load is enough because that makes all the initialization
51
5.67k
        // operations visible to us, and, this being a fast path, weaker
52
5.67k
        // ordering helps with performance. This `Acquire` synchronizes with
53
5.67k
        // `SeqCst` operations on the slow path.
54
5.67k
        self.queue.load(Ordering::Acquire) == COMPLETE_PTR
55
5.67k
    }
Unexecuted instantiation: _RNvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE14is_initializedCs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB5_8OnceCellpE14is_initializedB7_
56
57
    /// Safety: synchronizes with store to value via SeqCst read from state,
58
    /// writes value only once because we never get to INCOMPLETE state after a
59
    /// successful write.
60
    #[cold]
61
0
    pub(crate) fn initialize<F, E>(&self, f: F) -> Result<(), E>
62
0
    where
63
0
        F: FnOnce() -> Result<T, E>,
64
0
    {
65
0
        let mut f = Some(f);
66
0
        let mut res: Result<(), E> = Ok(());
67
0
        let slot: *mut Option<T> = self.value.get();
68
0
        initialize_or_wait(
69
0
            &self.queue,
70
0
            Some(&mut || {
71
0
                let f = unsafe { f.take().unwrap_unchecked() };
72
0
                match f() {
73
0
                    Ok(value) => {
74
0
                        unsafe { *slot = Some(value) };
75
0
                        true
76
                    }
77
0
                    Err(err) => {
78
0
                        res = Err(err);
79
0
                        false
80
                    }
81
                }
82
0
            }),
Unexecuted instantiation: _RNCINvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB8_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE10initializeNCINvMs4_NtBa_4syncINtB1P_8OnceCellBR_E11get_or_initNCNvB1L_10try_insert0E0NtNvMs4_B1P_IB20_pE11get_or_init4VoidE0Cs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNCINvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB8_8OnceCellpE10initializeppE0Ba_
83
0
        );
84
0
        res
85
0
    }
Unexecuted instantiation: _RINvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB6_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE10initializeNCINvMs4_NtB8_4syncINtB1N_8OnceCellBP_E11get_or_initNCNvB1J_10try_insert0E0NtNvMs4_B1N_IB1Y_pE11get_or_init4VoidECs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RINvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB6_8OnceCellpE10initializeppEB8_
86
87
    #[cold]
88
0
    pub(crate) fn wait(&self) {
89
0
        initialize_or_wait(&self.queue, None);
90
0
    }
91
92
    /// Get the reference to the underlying value, without checking if the cell
93
    /// is initialized.
94
    ///
95
    /// # Safety
96
    ///
97
    /// Caller must ensure that the cell is in initialized state, and that
98
    /// the contents are acquired by (synchronized to) this thread.
99
0
    pub(crate) unsafe fn get_unchecked(&self) -> &T {
100
0
        debug_assert!(self.is_initialized());
101
0
        let slot = &*self.value.get();
102
0
        slot.as_ref().unwrap_unchecked()
103
0
    }
Unexecuted instantiation: _RNvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE13get_uncheckedCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE13get_uncheckedCs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNvMs2_NtCsieqz2xIPOqY_9once_cell3impINtB5_8OnceCellpE13get_uncheckedB7_
104
105
    /// Gets the mutable reference to the underlying value.
106
    /// Returns `None` if the cell is empty.
107
0
    pub(crate) fn get_mut(&mut self) -> Option<&mut T> {
108
0
        // Safe b/c we have a unique access.
109
0
        unsafe { &mut *self.value.get() }.as_mut()
110
0
    }
111
112
    /// Consumes this `OnceCell`, returning the wrapped value.
113
    /// Returns `None` if the cell was empty.
114
    #[inline]
115
0
    pub(crate) fn into_inner(self) -> Option<T> {
116
0
        // Because `into_inner` takes `self` by value, the compiler statically
117
0
        // verifies that it is not currently borrowed.
118
0
        // So, it is safe to move out `Option<T>`.
119
0
        self.value.into_inner()
120
0
    }
121
}
122
123
// Three states that a OnceCell can be in, encoded into the lower bits of `queue` in
124
// the OnceCell structure.
125
const INCOMPLETE: usize = 0x0;
126
const RUNNING: usize = 0x1;
127
const COMPLETE: usize = 0x2;
128
const INCOMPLETE_PTR: *mut Waiter = INCOMPLETE as *mut Waiter;
129
const COMPLETE_PTR: *mut Waiter = COMPLETE as *mut Waiter;
130
131
// Mask to learn about the state. All other bits are the queue of waiters if
132
// this is in the RUNNING state.
133
const STATE_MASK: usize = 0x3;
134
135
/// Representation of a node in the linked list of waiters in the RUNNING state.
136
/// A waiters is stored on the stack of the waiting threads.
137
#[repr(align(4))] // Ensure the two lower bits are free to use as state bits.
138
struct Waiter {
139
    thread: Cell<Option<Thread>>,
140
    signaled: AtomicBool,
141
    next: *mut Waiter,
142
}
143
144
/// Drains and notifies the queue of waiters on drop.
145
struct Guard<'a> {
146
    queue: &'a AtomicPtr<Waiter>,
147
    new_queue: *mut Waiter,
148
}
149
150
impl Drop for Guard<'_> {
151
0
    fn drop(&mut self) {
152
0
        let queue = self.queue.swap(self.new_queue, Ordering::AcqRel);
153
0
154
0
        let state = strict::addr(queue) & STATE_MASK;
155
0
        assert_eq!(state, RUNNING);
156
157
        unsafe {
158
0
            let mut waiter = strict::map_addr(queue, |q| q & !STATE_MASK);
159
0
            while !waiter.is_null() {
160
0
                let next = (*waiter).next;
161
0
                let thread = (*waiter).thread.take().unwrap();
162
0
                (*waiter).signaled.store(true, Ordering::Release);
163
0
                waiter = next;
164
0
                thread.unpark();
165
0
            }
166
        }
167
0
    }
168
}
169
170
// Corresponds to `std::sync::Once::call_inner`.
171
//
172
// Originally copied from std, but since modified to remove poisoning and to
173
// support wait.
174
//
175
// Note: this is intentionally monomorphic
176
#[inline(never)]
177
0
fn initialize_or_wait(queue: &AtomicPtr<Waiter>, mut init: Option<&mut dyn FnMut() -> bool>) {
178
0
    let mut curr_queue = queue.load(Ordering::Acquire);
179
180
0
    loop {
181
0
        let curr_state = strict::addr(curr_queue) & STATE_MASK;
182
0
        match (curr_state, &mut init) {
183
0
            (COMPLETE, _) => return,
184
0
            (INCOMPLETE, Some(init)) => {
185
0
                let exchange = queue.compare_exchange(
186
0
                    curr_queue,
187
0
                    strict::map_addr(curr_queue, |q| (q & !STATE_MASK) | RUNNING),
188
0
                    Ordering::Acquire,
189
0
                    Ordering::Acquire,
190
0
                );
191
0
                if let Err(new_queue) = exchange {
192
0
                    curr_queue = new_queue;
193
0
                    continue;
194
0
                }
195
0
                let mut guard = Guard { queue, new_queue: INCOMPLETE_PTR };
196
0
                if init() {
197
0
                    guard.new_queue = COMPLETE_PTR;
198
0
                }
199
0
                return;
200
            }
201
0
            (INCOMPLETE, None) | (RUNNING, _) => {
202
0
                wait(queue, curr_queue);
203
0
                curr_queue = queue.load(Ordering::Acquire);
204
0
            }
205
0
            _ => debug_assert!(false),
206
        }
207
    }
208
0
}
209
210
0
fn wait(queue: &AtomicPtr<Waiter>, mut curr_queue: *mut Waiter) {
211
0
    let curr_state = strict::addr(curr_queue) & STATE_MASK;
212
0
    loop {
213
0
        let node = Waiter {
214
0
            thread: Cell::new(Some(thread::current())),
215
0
            signaled: AtomicBool::new(false),
216
0
            next: strict::map_addr(curr_queue, |q| q & !STATE_MASK),
217
0
        };
218
0
        let me = &node as *const Waiter as *mut Waiter;
219
0
220
0
        let exchange = queue.compare_exchange(
221
0
            curr_queue,
222
0
            strict::map_addr(me, |q| q | curr_state),
223
0
            Ordering::Release,
224
0
            Ordering::Relaxed,
225
0
        );
226
0
        if let Err(new_queue) = exchange {
227
0
            if strict::addr(new_queue) & STATE_MASK != curr_state {
228
0
                return;
229
0
            }
230
0
            curr_queue = new_queue;
231
0
            continue;
232
0
        }
233
234
0
        while !node.signaled.load(Ordering::Acquire) {
235
0
            thread::park();
236
0
        }
237
0
        break;
238
    }
239
0
}
240
241
// Polyfill of strict provenance from https://crates.io/crates/sptr.
242
//
243
// Use free-standing function rather than a trait to keep things simple and
244
// avoid any potential conflicts with future stabile std API.
245
mod strict {
246
    #[must_use]
247
    #[inline]
248
0
    pub(crate) fn addr<T>(ptr: *mut T) -> usize
249
0
    where
250
0
        T: Sized,
251
0
    {
252
0
        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
253
0
        // SAFETY: Pointer-to-integer transmutes are valid (if you are okay with losing the
254
0
        // provenance).
255
0
        unsafe { core::mem::transmute(ptr) }
256
0
    }
257
258
    #[must_use]
259
    #[inline]
260
0
    pub(crate) fn with_addr<T>(ptr: *mut T, addr: usize) -> *mut T
261
0
    where
262
0
        T: Sized,
263
0
    {
264
0
        // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
265
0
        //
266
0
        // In the mean-time, this operation is defined to be "as if" it was
267
0
        // a wrapping_offset, so we can emulate it as such. This should properly
268
0
        // restore pointer provenance even under today's compiler.
269
0
        let self_addr = self::addr(ptr) as isize;
270
0
        let dest_addr = addr as isize;
271
0
        let offset = dest_addr.wrapping_sub(self_addr);
272
0
273
0
        // This is the canonical desugarring of this operation,
274
0
        // but `pointer::cast` was only stabilized in 1.38.
275
0
        // self.cast::<u8>().wrapping_offset(offset).cast::<T>()
276
0
        (ptr as *mut u8).wrapping_offset(offset) as *mut T
277
0
    }
278
279
    #[must_use]
280
    #[inline]
281
0
    pub(crate) fn map_addr<T>(ptr: *mut T, f: impl FnOnce(usize) -> usize) -> *mut T
282
0
    where
283
0
        T: Sized,
284
0
    {
285
0
        self::with_addr(ptr, f(addr(ptr)))
286
0
    }
Unexecuted instantiation: _RINvNtNtCsieqz2xIPOqY_9once_cell3imp6strict8map_addrNtB4_6WaiterNCNvXs3_B4_NtB4_5GuardNtNtNtCs1ujR1JRCAmI_4core3ops4drop4Drop4drop0EB6_
Unexecuted instantiation: _RINvNtNtCsieqz2xIPOqY_9once_cell3imp6strict8map_addrNtB4_6WaiterNCNvB4_18initialize_or_wait0EB6_
Unexecuted instantiation: _RINvNtNtCsieqz2xIPOqY_9once_cell3imp6strict8map_addrNtB4_6WaiterNCNvB4_4wait0EB6_
Unexecuted instantiation: _RINvNtNtCsieqz2xIPOqY_9once_cell3imp6strict8map_addrNtB4_6WaiterNCNvB4_4waits_0EB6_
287
}
288
289
// These test are snatched from std as well.
290
#[cfg(test)]
291
mod tests {
292
    use std::panic;
293
    use std::{sync::mpsc::channel, thread};
294
295
    use super::OnceCell;
296
297
    impl<T> OnceCell<T> {
298
        fn init(&self, f: impl FnOnce() -> T) {
299
            enum Void {}
300
            let _ = self.initialize(|| Ok::<T, Void>(f()));
301
        }
302
    }
303
304
    #[test]
305
    fn smoke_once() {
306
        static O: OnceCell<()> = OnceCell::new();
307
        let mut a = 0;
308
        O.init(|| a += 1);
309
        assert_eq!(a, 1);
310
        O.init(|| a += 1);
311
        assert_eq!(a, 1);
312
    }
313
314
    #[test]
315
    fn stampede_once() {
316
        static O: OnceCell<()> = OnceCell::new();
317
        static mut RUN: bool = false;
318
319
        let (tx, rx) = channel();
320
        for _ in 0..10 {
321
            let tx = tx.clone();
322
            thread::spawn(move || {
323
                for _ in 0..4 {
324
                    thread::yield_now()
325
                }
326
                unsafe {
327
                    O.init(|| {
328
                        assert!(!RUN);
329
                        RUN = true;
330
                    });
331
                    assert!(RUN);
332
                }
333
                tx.send(()).unwrap();
334
            });
335
        }
336
337
        unsafe {
338
            O.init(|| {
339
                assert!(!RUN);
340
                RUN = true;
341
            });
342
            assert!(RUN);
343
        }
344
345
        for _ in 0..10 {
346
            rx.recv().unwrap();
347
        }
348
    }
349
350
    #[test]
351
    fn poison_bad() {
352
        static O: OnceCell<()> = OnceCell::new();
353
354
        // poison the once
355
        let t = panic::catch_unwind(|| {
356
            O.init(|| panic!());
357
        });
358
        assert!(t.is_err());
359
360
        // we can subvert poisoning, however
361
        let mut called = false;
362
        O.init(|| {
363
            called = true;
364
        });
365
        assert!(called);
366
367
        // once any success happens, we stop propagating the poison
368
        O.init(|| {});
369
    }
370
371
    #[test]
372
    fn wait_for_force_to_finish() {
373
        static O: OnceCell<()> = OnceCell::new();
374
375
        // poison the once
376
        let t = panic::catch_unwind(|| {
377
            O.init(|| panic!());
378
        });
379
        assert!(t.is_err());
380
381
        // make sure someone's waiting inside the once via a force
382
        let (tx1, rx1) = channel();
383
        let (tx2, rx2) = channel();
384
        let t1 = thread::spawn(move || {
385
            O.init(|| {
386
                tx1.send(()).unwrap();
387
                rx2.recv().unwrap();
388
            });
389
        });
390
391
        rx1.recv().unwrap();
392
393
        // put another waiter on the once
394
        let t2 = thread::spawn(|| {
395
            let mut called = false;
396
            O.init(|| {
397
                called = true;
398
            });
399
            assert!(!called);
400
        });
401
402
        tx2.send(()).unwrap();
403
404
        assert!(t1.join().is_ok());
405
        assert!(t2.join().is_ok());
406
    }
407
408
    #[test]
409
    #[cfg(target_pointer_width = "64")]
410
    fn test_size() {
411
        use std::mem::size_of;
412
413
        assert_eq!(size_of::<OnceCell<u32>>(), 4 * size_of::<u32>());
414
    }
415
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.19.0/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! # Overview
2
//!
3
//! `once_cell` provides two new cell-like types, [`unsync::OnceCell`] and
4
//! [`sync::OnceCell`]. A `OnceCell` might store arbitrary non-`Copy` types, can
5
//! be assigned to at most once and provides direct access to the stored
6
//! contents. The core API looks *roughly* like this (and there's much more
7
//! inside, read on!):
8
//!
9
//! ```rust,ignore
10
//! impl<T> OnceCell<T> {
11
//!     const fn new() -> OnceCell<T> { ... }
12
//!     fn set(&self, value: T) -> Result<(), T> { ... }
13
//!     fn get(&self) -> Option<&T> { ... }
14
//! }
15
//! ```
16
//!
17
//! Note that, like with [`RefCell`] and [`Mutex`], the `set` method requires
18
//! only a shared reference. Because of the single assignment restriction `get`
19
//! can return a `&T` instead of `Ref<T>` or `MutexGuard<T>`.
20
//!
21
//! The `sync` flavor is thread-safe (that is, implements the [`Sync`] trait),
22
//! while the `unsync` one is not.
23
//!
24
//! [`unsync::OnceCell`]: unsync/struct.OnceCell.html
25
//! [`sync::OnceCell`]: sync/struct.OnceCell.html
26
//! [`RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
27
//! [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
28
//! [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
29
//!
30
//! # Recipes
31
//!
32
//! `OnceCell` might be useful for a variety of patterns.
33
//!
34
//! ## Safe Initialization of Global Data
35
//!
36
//! ```rust
37
//! use std::{env, io};
38
//!
39
//! use once_cell::sync::OnceCell;
40
//!
41
//! #[derive(Debug)]
42
//! pub struct Logger {
43
//!     // ...
44
//! }
45
//! static INSTANCE: OnceCell<Logger> = OnceCell::new();
46
//!
47
//! impl Logger {
48
//!     pub fn global() -> &'static Logger {
49
//!         INSTANCE.get().expect("logger is not initialized")
50
//!     }
51
//!
52
//!     fn from_cli(args: env::Args) -> Result<Logger, std::io::Error> {
53
//!        // ...
54
//! #      Ok(Logger {})
55
//!     }
56
//! }
57
//!
58
//! fn main() {
59
//!     let logger = Logger::from_cli(env::args()).unwrap();
60
//!     INSTANCE.set(logger).unwrap();
61
//!     // use `Logger::global()` from now on
62
//! }
63
//! ```
64
//!
65
//! ## Lazy Initialized Global Data
66
//!
67
//! This is essentially the `lazy_static!` macro, but without a macro.
68
//!
69
//! ```rust
70
//! use std::{sync::Mutex, collections::HashMap};
71
//!
72
//! use once_cell::sync::OnceCell;
73
//!
74
//! fn global_data() -> &'static Mutex<HashMap<i32, String>> {
75
//!     static INSTANCE: OnceCell<Mutex<HashMap<i32, String>>> = OnceCell::new();
76
//!     INSTANCE.get_or_init(|| {
77
//!         let mut m = HashMap::new();
78
//!         m.insert(13, "Spica".to_string());
79
//!         m.insert(74, "Hoyten".to_string());
80
//!         Mutex::new(m)
81
//!     })
82
//! }
83
//! ```
84
//!
85
//! There are also the [`sync::Lazy`] and [`unsync::Lazy`] convenience types to
86
//! streamline this pattern:
87
//!
88
//! ```rust
89
//! use std::{sync::Mutex, collections::HashMap};
90
//! use once_cell::sync::Lazy;
91
//!
92
//! static GLOBAL_DATA: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| {
93
//!     let mut m = HashMap::new();
94
//!     m.insert(13, "Spica".to_string());
95
//!     m.insert(74, "Hoyten".to_string());
96
//!     Mutex::new(m)
97
//! });
98
//!
99
//! fn main() {
100
//!     println!("{:?}", GLOBAL_DATA.lock().unwrap());
101
//! }
102
//! ```
103
//!
104
//! Note that the variable that holds `Lazy` is declared as `static`, *not*
105
//! `const`. This is important: using `const` instead compiles, but works wrong.
106
//!
107
//! [`sync::Lazy`]: sync/struct.Lazy.html
108
//! [`unsync::Lazy`]: unsync/struct.Lazy.html
109
//!
110
//! ## General purpose lazy evaluation
111
//!
112
//! Unlike `lazy_static!`, `Lazy` works with local variables.
113
//!
114
//! ```rust
115
//! use once_cell::unsync::Lazy;
116
//!
117
//! fn main() {
118
//!     let ctx = vec![1, 2, 3];
119
//!     let thunk = Lazy::new(|| {
120
//!         ctx.iter().sum::<i32>()
121
//!     });
122
//!     assert_eq!(*thunk, 6);
123
//! }
124
//! ```
125
//!
126
//! If you need a lazy field in a struct, you probably should use `OnceCell`
127
//! directly, because that will allow you to access `self` during
128
//! initialization.
129
//!
130
//! ```rust
131
//! use std::{fs, path::PathBuf};
132
//!
133
//! use once_cell::unsync::OnceCell;
134
//!
135
//! struct Ctx {
136
//!     config_path: PathBuf,
137
//!     config: OnceCell<String>,
138
//! }
139
//!
140
//! impl Ctx {
141
//!     pub fn get_config(&self) -> Result<&str, std::io::Error> {
142
//!         let cfg = self.config.get_or_try_init(|| {
143
//!             fs::read_to_string(&self.config_path)
144
//!         })?;
145
//!         Ok(cfg.as_str())
146
//!     }
147
//! }
148
//! ```
149
//!
150
//! ## Lazily Compiled Regex
151
//!
152
//! This is a `regex!` macro which takes a string literal and returns an
153
//! *expression* that evaluates to a `&'static Regex`:
154
//!
155
//! ```
156
//! macro_rules! regex {
157
//!     ($re:literal $(,)?) => {{
158
//!         static RE: once_cell::sync::OnceCell<regex::Regex> = once_cell::sync::OnceCell::new();
159
//!         RE.get_or_init(|| regex::Regex::new($re).unwrap())
160
//!     }};
161
//! }
162
//! ```
163
//!
164
//! This macro can be useful to avoid the "compile regex on every loop
165
//! iteration" problem.
166
//!
167
//! ## Runtime `include_bytes!`
168
//!
169
//! The `include_bytes` macro is useful to include test resources, but it slows
170
//! down test compilation a lot. An alternative is to load the resources at
171
//! runtime:
172
//!
173
//! ```
174
//! use std::path::Path;
175
//!
176
//! use once_cell::sync::OnceCell;
177
//!
178
//! pub struct TestResource {
179
//!     path: &'static str,
180
//!     cell: OnceCell<Vec<u8>>,
181
//! }
182
//!
183
//! impl TestResource {
184
//!     pub const fn new(path: &'static str) -> TestResource {
185
//!         TestResource { path, cell: OnceCell::new() }
186
//!     }
187
//!     pub fn bytes(&self) -> &[u8] {
188
//!         self.cell.get_or_init(|| {
189
//!             let dir = std::env::var("CARGO_MANIFEST_DIR").unwrap();
190
//!             let path = Path::new(dir.as_str()).join(self.path);
191
//!             std::fs::read(&path).unwrap_or_else(|_err| {
192
//!                 panic!("failed to load test resource: {}", path.display())
193
//!             })
194
//!         }).as_slice()
195
//!     }
196
//! }
197
//!
198
//! static TEST_IMAGE: TestResource = TestResource::new("test_data/lena.png");
199
//!
200
//! #[test]
201
//! fn test_sobel_filter() {
202
//!     let rgb: &[u8] = TEST_IMAGE.bytes();
203
//!     // ...
204
//! # drop(rgb);
205
//! }
206
//! ```
207
//!
208
//! ## `lateinit`
209
//!
210
//! `LateInit` type for delayed initialization. It is reminiscent of Kotlin's
211
//! `lateinit` keyword and allows construction of cyclic data structures:
212
//!
213
//!
214
//! ```
215
//! use once_cell::sync::OnceCell;
216
//!
217
//! pub struct LateInit<T> { cell: OnceCell<T> }
218
//!
219
//! impl<T> LateInit<T> {
220
//!     pub fn init(&self, value: T) {
221
//!         assert!(self.cell.set(value).is_ok())
222
//!     }
223
//! }
224
//!
225
//! impl<T> Default for LateInit<T> {
226
//!     fn default() -> Self { LateInit { cell: OnceCell::default() } }
227
//! }
228
//!
229
//! impl<T> std::ops::Deref for LateInit<T> {
230
//!     type Target = T;
231
//!     fn deref(&self) -> &T {
232
//!         self.cell.get().unwrap()
233
//!     }
234
//! }
235
//!
236
//! #[derive(Default)]
237
//! struct A<'a> {
238
//!     b: LateInit<&'a B<'a>>,
239
//! }
240
//!
241
//! #[derive(Default)]
242
//! struct B<'a> {
243
//!     a: LateInit<&'a A<'a>>
244
//! }
245
//!
246
//!
247
//! fn build_cycle() {
248
//!     let a = A::default();
249
//!     let b = B::default();
250
//!     a.b.init(&b);
251
//!     b.a.init(&a);
252
//!
253
//!     let _a = &a.b.a.b.a;
254
//! }
255
//! ```
256
//!
257
//! # Comparison with std
258
//!
259
//! |`!Sync` types         | Access Mode            | Drawbacks                                     |
260
//! |----------------------|------------------------|-----------------------------------------------|
261
//! |`Cell<T>`             | `T`                    | requires `T: Copy` for `get`                  |
262
//! |`RefCell<T>`          | `RefMut<T>` / `Ref<T>` | may panic at runtime                          |
263
//! |`unsync::OnceCell<T>` | `&T`                   | assignable only once                          |
264
//!
265
//! |`Sync` types          | Access Mode            | Drawbacks                                     |
266
//! |----------------------|------------------------|-----------------------------------------------|
267
//! |`AtomicT`             | `T`                    | works only with certain `Copy` types          |
268
//! |`Mutex<T>`            | `MutexGuard<T>`        | may deadlock at runtime, may block the thread |
269
//! |`sync::OnceCell<T>`   | `&T`                   | assignable only once, may block the thread    |
270
//!
271
//! Technically, calling `get_or_init` will also cause a panic or a deadlock if
272
//! it recursively calls itself. However, because the assignment can happen only
273
//! once, such cases should be more rare than equivalents with `RefCell` and
274
//! `Mutex`.
275
//!
276
//! # Minimum Supported `rustc` Version
277
//!
278
//! If only the `std`, `alloc`, or `race` features are enabled, MSRV will be
279
//! updated conservatively, supporting at least latest 8 versions of the compiler.
280
//! When using other features, like `parking_lot`, MSRV might be updated more
281
//! frequently, up to the latest stable. In both cases, increasing MSRV is *not*
282
//! considered a semver-breaking change and requires only a minor version bump.
283
//!
284
//! # Implementation details
285
//!
286
//! The implementation is based on the
287
//! [`lazy_static`](https://github.com/rust-lang-nursery/lazy-static.rs/) and
288
//! [`lazy_cell`](https://github.com/indiv0/lazycell/) crates and
289
//! [`std::sync::Once`]. In some sense, `once_cell` just streamlines and unifies
290
//! those APIs.
291
//!
292
//! To implement a sync flavor of `OnceCell`, this crates uses either a custom
293
//! re-implementation of `std::sync::Once` or `parking_lot::Mutex`. This is
294
//! controlled by the `parking_lot` feature (disabled by default). Performance
295
//! is the same for both cases, but the `parking_lot` based `OnceCell<T>` is
296
//! smaller by up to 16 bytes.
297
//!
298
//! This crate uses `unsafe`.
299
//!
300
//! [`std::sync::Once`]: https://doc.rust-lang.org/std/sync/struct.Once.html
301
//!
302
//! # F.A.Q.
303
//!
304
//! **Should I use the sync or unsync flavor?**
305
//!
306
//! Because Rust compiler checks thread safety for you, it's impossible to
307
//! accidentally use `unsync` where `sync` is required. So, use `unsync` in
308
//! single-threaded code and `sync` in multi-threaded. It's easy to switch
309
//! between the two if code becomes multi-threaded later.
310
//!
311
//! At the moment, `unsync` has an additional benefit that reentrant
312
//! initialization causes a panic, which might be easier to debug than a
313
//! deadlock.
314
//!
315
//! **Does this crate support async?**
316
//!
317
//! No, but you can use
318
//! [`async_once_cell`](https://crates.io/crates/async_once_cell) instead.
319
//!
320
//! **Does this crate support `no_std`?**
321
//!
322
//! Yes, but with caveats. `OnceCell` is a synchronization primitive which
323
//! _semantically_ relies on blocking. `OnceCell` guarantees that at most one
324
//! `f` will be called to compute the value. If two threads of execution call
325
//! `get_or_init` concurrently, one of them has to wait.
326
//!
327
//! Waiting fundamentally requires OS support. Execution environment needs to
328
//! understand who waits on whom to prevent deadlocks due to priority inversion.
329
//! You _could_ make code to compile by blindly using pure spinlocks, but the
330
//! runtime behavior would be subtly wrong.
331
//!
332
//! Given these constraints, `once_cell` provides the following options:
333
//!
334
//! - The `race` module provides similar, but distinct synchronization primitive
335
//!   which is compatible with `no_std`. With `race`, the `f` function can be
336
//!   called multiple times by different threads, but only one thread will win
337
//!   to install the value.
338
//! - `critical-section` feature (with a `-`, not `_`) uses `critical_section`
339
//!   to implement blocking.
340
//!
341
//! **Can I bring my own mutex?**
342
//!
343
//! There is [generic_once_cell](https://crates.io/crates/generic_once_cell) to
344
//! allow just that.
345
//!
346
//! **Should I use `std::cell::OnceCell`, `once_cell`, or `lazy_static`?**
347
//!
348
//! If you can use `std` version (your MSRV is at least 1.70, and you don't need
349
//! extra features `once_cell` provides), use `std`. Otherwise, use `once_cell`.
350
//! Don't use `lazy_static`.
351
//!
352
//! # Related crates
353
//!
354
//! * Most of this crate's functionality is available in `std` starting with
355
//!   Rust 1.70. See `std::cell::OnceCell` and `std::sync::OnceLock`.
356
//! * [double-checked-cell](https://github.com/niklasf/double-checked-cell)
357
//! * [lazy-init](https://crates.io/crates/lazy-init)
358
//! * [lazycell](https://crates.io/crates/lazycell)
359
//! * [mitochondria](https://crates.io/crates/mitochondria)
360
//! * [lazy_static](https://crates.io/crates/lazy_static)
361
//! * [async_once_cell](https://crates.io/crates/async_once_cell)
362
//! * [generic_once_cell](https://crates.io/crates/generic_once_cell) (bring
363
//!   your own mutex)
364
365
#![cfg_attr(not(feature = "std"), no_std)]
366
367
#[cfg(feature = "alloc")]
368
extern crate alloc;
369
370
#[cfg(all(feature = "critical-section", not(feature = "std")))]
371
#[path = "imp_cs.rs"]
372
mod imp;
373
374
#[cfg(all(feature = "std", feature = "parking_lot"))]
375
#[path = "imp_pl.rs"]
376
mod imp;
377
378
#[cfg(all(feature = "std", not(feature = "parking_lot")))]
379
#[path = "imp_std.rs"]
380
mod imp;
381
382
/// Single-threaded version of `OnceCell`.
383
pub mod unsync {
384
    use core::{
385
        cell::{Cell, UnsafeCell},
386
        fmt, mem,
387
        ops::{Deref, DerefMut},
388
        panic::{RefUnwindSafe, UnwindSafe},
389
    };
390
391
    /// A cell which can be written to only once. It is not thread safe.
392
    ///
393
    /// Unlike [`std::cell::RefCell`], a `OnceCell` provides simple `&`
394
    /// references to the contents.
395
    ///
396
    /// [`std::cell::RefCell`]: https://doc.rust-lang.org/std/cell/struct.RefCell.html
397
    ///
398
    /// # Example
399
    /// ```
400
    /// use once_cell::unsync::OnceCell;
401
    ///
402
    /// let cell = OnceCell::new();
403
    /// assert!(cell.get().is_none());
404
    ///
405
    /// let value: &String = cell.get_or_init(|| {
406
    ///     "Hello, World!".to_string()
407
    /// });
408
    /// assert_eq!(value, "Hello, World!");
409
    /// assert!(cell.get().is_some());
410
    /// ```
411
    pub struct OnceCell<T> {
412
        // Invariant: written to at most once.
413
        inner: UnsafeCell<Option<T>>,
414
    }
415
416
    // Similarly to a `Sync` bound on `sync::OnceCell`, we can use
417
    // `&unsync::OnceCell` to sneak a `T` through `catch_unwind`,
418
    // by initializing the cell in closure and extracting the value in the
419
    // `Drop`.
420
    impl<T: RefUnwindSafe + UnwindSafe> RefUnwindSafe for OnceCell<T> {}
421
    impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
422
423
    impl<T> Default for OnceCell<T> {
424
0
        fn default() -> Self {
425
0
            Self::new()
426
0
        }
427
    }
428
429
    impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
430
0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
431
0
            match self.get() {
432
0
                Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
433
0
                None => f.write_str("OnceCell(Uninit)"),
434
            }
435
0
        }
436
    }
437
438
    impl<T: Clone> Clone for OnceCell<T> {
439
0
        fn clone(&self) -> OnceCell<T> {
440
0
            match self.get() {
441
0
                Some(value) => OnceCell::with_value(value.clone()),
442
0
                None => OnceCell::new(),
443
            }
444
0
        }
445
446
0
        fn clone_from(&mut self, source: &Self) {
447
0
            match (self.get_mut(), source.get()) {
448
0
                (Some(this), Some(source)) => this.clone_from(source),
449
0
                _ => *self = source.clone(),
450
            }
451
0
        }
452
    }
453
454
    impl<T: PartialEq> PartialEq for OnceCell<T> {
455
0
        fn eq(&self, other: &Self) -> bool {
456
0
            self.get() == other.get()
457
0
        }
458
    }
459
460
    impl<T: Eq> Eq for OnceCell<T> {}
461
462
    impl<T> From<T> for OnceCell<T> {
463
0
        fn from(value: T) -> Self {
464
0
            OnceCell::with_value(value)
465
0
        }
466
    }
467
468
    impl<T> OnceCell<T> {
469
        /// Creates a new empty cell.
470
0
        pub const fn new() -> OnceCell<T> {
471
0
            OnceCell { inner: UnsafeCell::new(None) }
472
0
        }
473
474
        /// Creates a new initialized cell.
475
0
        pub const fn with_value(value: T) -> OnceCell<T> {
476
0
            OnceCell { inner: UnsafeCell::new(Some(value)) }
477
0
        }
478
479
        /// Gets a reference to the underlying value.
480
        ///
481
        /// Returns `None` if the cell is empty.
482
        #[inline]
483
0
        pub fn get(&self) -> Option<&T> {
484
0
            // Safe due to `inner`'s invariant of being written to at most once.
485
0
            // Had multiple writes to `inner` been allowed, a reference to the
486
0
            // value we return now would become dangling by a write of a
487
0
            // different value later.
488
0
            unsafe { &*self.inner.get() }.as_ref()
489
0
        }
490
491
        /// Gets a mutable reference to the underlying value.
492
        ///
493
        /// Returns `None` if the cell is empty.
494
        ///
495
        /// This method is allowed to violate the invariant of writing to a `OnceCell`
496
        /// at most once because it requires `&mut` access to `self`. As with all
497
        /// interior mutability, `&mut` access permits arbitrary modification:
498
        ///
499
        /// ```
500
        /// use once_cell::unsync::OnceCell;
501
        ///
502
        /// let mut cell: OnceCell<u32> = OnceCell::new();
503
        /// cell.set(92).unwrap();
504
        /// *cell.get_mut().unwrap() = 93;
505
        /// assert_eq!(cell.get(), Some(&93));
506
        /// ```
507
        #[inline]
508
0
        pub fn get_mut(&mut self) -> Option<&mut T> {
509
0
            // Safe because we have unique access
510
0
            unsafe { &mut *self.inner.get() }.as_mut()
511
0
        }
512
513
        /// Sets the contents of this cell to `value`.
514
        ///
515
        /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
516
        /// full.
517
        ///
518
        /// # Example
519
        /// ```
520
        /// use once_cell::unsync::OnceCell;
521
        ///
522
        /// let cell = OnceCell::new();
523
        /// assert!(cell.get().is_none());
524
        ///
525
        /// assert_eq!(cell.set(92), Ok(()));
526
        /// assert_eq!(cell.set(62), Err(62));
527
        ///
528
        /// assert!(cell.get().is_some());
529
        /// ```
530
0
        pub fn set(&self, value: T) -> Result<(), T> {
531
0
            match self.try_insert(value) {
532
0
                Ok(_) => Ok(()),
533
0
                Err((_, value)) => Err(value),
534
            }
535
0
        }
536
537
        /// Like [`set`](Self::set), but also returns a reference to the final cell value.
538
        ///
539
        /// # Example
540
        /// ```
541
        /// use once_cell::unsync::OnceCell;
542
        ///
543
        /// let cell = OnceCell::new();
544
        /// assert!(cell.get().is_none());
545
        ///
546
        /// assert_eq!(cell.try_insert(92), Ok(&92));
547
        /// assert_eq!(cell.try_insert(62), Err((&92, 62)));
548
        ///
549
        /// assert!(cell.get().is_some());
550
        /// ```
551
0
        pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
552
0
            if let Some(old) = self.get() {
553
0
                return Err((old, value));
554
0
            }
555
0
556
0
            let slot = unsafe { &mut *self.inner.get() };
557
0
            // This is the only place where we set the slot, no races
558
0
            // due to reentrancy/concurrency are possible, and we've
559
0
            // checked that slot is currently `None`, so this write
560
0
            // maintains the `inner`'s invariant.
561
0
            *slot = Some(value);
562
0
            Ok(unsafe { slot.as_ref().unwrap_unchecked() })
563
0
        }
564
565
        /// Gets the contents of the cell, initializing it with `f`
566
        /// if the cell was empty.
567
        ///
568
        /// # Panics
569
        ///
570
        /// If `f` panics, the panic is propagated to the caller, and the cell
571
        /// remains uninitialized.
572
        ///
573
        /// It is an error to reentrantly initialize the cell from `f`. Doing
574
        /// so results in a panic.
575
        ///
576
        /// # Example
577
        /// ```
578
        /// use once_cell::unsync::OnceCell;
579
        ///
580
        /// let cell = OnceCell::new();
581
        /// let value = cell.get_or_init(|| 92);
582
        /// assert_eq!(value, &92);
583
        /// let value = cell.get_or_init(|| unreachable!());
584
        /// assert_eq!(value, &92);
585
        /// ```
586
0
        pub fn get_or_init<F>(&self, f: F) -> &T
587
0
        where
588
0
            F: FnOnce() -> T,
589
0
        {
590
0
            enum Void {}
591
0
            match self.get_or_try_init(|| Ok::<T, Void>(f())) {
592
0
                Ok(val) => val,
593
0
                Err(void) => match void {},
594
0
            }
595
0
        }
596
597
        /// Gets the contents of the cell, initializing it with `f` if
598
        /// the cell was empty. If the cell was empty and `f` failed, an
599
        /// error is returned.
600
        ///
601
        /// # Panics
602
        ///
603
        /// If `f` panics, the panic is propagated to the caller, and the cell
604
        /// remains uninitialized.
605
        ///
606
        /// It is an error to reentrantly initialize the cell from `f`. Doing
607
        /// so results in a panic.
608
        ///
609
        /// # Example
610
        /// ```
611
        /// use once_cell::unsync::OnceCell;
612
        ///
613
        /// let cell = OnceCell::new();
614
        /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
615
        /// assert!(cell.get().is_none());
616
        /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
617
        ///     Ok(92)
618
        /// });
619
        /// assert_eq!(value, Ok(&92));
620
        /// assert_eq!(cell.get(), Some(&92))
621
        /// ```
622
0
        pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
623
0
        where
624
0
            F: FnOnce() -> Result<T, E>,
625
0
        {
626
0
            if let Some(val) = self.get() {
627
0
                return Ok(val);
628
0
            }
629
0
            let val = f()?;
630
            // Note that *some* forms of reentrant initialization might lead to
631
            // UB (see `reentrant_init` test). I believe that just removing this
632
            // `assert`, while keeping `set/get` would be sound, but it seems
633
            // better to panic, rather than to silently use an old value.
634
0
            assert!(self.set(val).is_ok(), "reentrant init");
635
0
            Ok(unsafe { self.get().unwrap_unchecked() })
636
0
        }
637
638
        /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
639
        ///
640
        /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
641
        ///
642
        /// # Examples
643
        ///
644
        /// ```
645
        /// use once_cell::unsync::OnceCell;
646
        ///
647
        /// let mut cell: OnceCell<String> = OnceCell::new();
648
        /// assert_eq!(cell.take(), None);
649
        ///
650
        /// let mut cell = OnceCell::new();
651
        /// cell.set("hello".to_string()).unwrap();
652
        /// assert_eq!(cell.take(), Some("hello".to_string()));
653
        /// assert_eq!(cell.get(), None);
654
        /// ```
655
        ///
656
        /// This method is allowed to violate the invariant of writing to a `OnceCell`
657
        /// at most once because it requires `&mut` access to `self`. As with all
658
        /// interior mutability, `&mut` access permits arbitrary modification:
659
        ///
660
        /// ```
661
        /// use once_cell::unsync::OnceCell;
662
        ///
663
        /// let mut cell: OnceCell<u32> = OnceCell::new();
664
        /// cell.set(92).unwrap();
665
        /// cell = OnceCell::new();
666
        /// ```
667
0
        pub fn take(&mut self) -> Option<T> {
668
0
            mem::take(self).into_inner()
669
0
        }
670
671
        /// Consumes the `OnceCell`, returning the wrapped value.
672
        ///
673
        /// Returns `None` if the cell was empty.
674
        ///
675
        /// # Examples
676
        ///
677
        /// ```
678
        /// use once_cell::unsync::OnceCell;
679
        ///
680
        /// let cell: OnceCell<String> = OnceCell::new();
681
        /// assert_eq!(cell.into_inner(), None);
682
        ///
683
        /// let cell = OnceCell::new();
684
        /// cell.set("hello".to_string()).unwrap();
685
        /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
686
        /// ```
687
0
        pub fn into_inner(self) -> Option<T> {
688
0
            // Because `into_inner` takes `self` by value, the compiler statically verifies
689
0
            // that it is not currently borrowed. So it is safe to move out `Option<T>`.
690
0
            self.inner.into_inner()
691
0
        }
692
    }
693
694
    /// A value which is initialized on the first access.
695
    ///
696
    /// # Example
697
    /// ```
698
    /// use once_cell::unsync::Lazy;
699
    ///
700
    /// let lazy: Lazy<i32> = Lazy::new(|| {
701
    ///     println!("initializing");
702
    ///     92
703
    /// });
704
    /// println!("ready");
705
    /// println!("{}", *lazy);
706
    /// println!("{}", *lazy);
707
    ///
708
    /// // Prints:
709
    /// //   ready
710
    /// //   initializing
711
    /// //   92
712
    /// //   92
713
    /// ```
714
    pub struct Lazy<T, F = fn() -> T> {
715
        cell: OnceCell<T>,
716
        init: Cell<Option<F>>,
717
    }
718
719
    impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
720
721
    impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
722
0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
723
0
            f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
724
0
        }
725
    }
726
727
    impl<T, F> Lazy<T, F> {
728
        /// Creates a new lazy value with the given initializing function.
729
        ///
730
        /// # Example
731
        /// ```
732
        /// # fn main() {
733
        /// use once_cell::unsync::Lazy;
734
        ///
735
        /// let hello = "Hello, World!".to_string();
736
        ///
737
        /// let lazy = Lazy::new(|| hello.to_uppercase());
738
        ///
739
        /// assert_eq!(&*lazy, "HELLO, WORLD!");
740
        /// # }
741
        /// ```
742
0
        pub const fn new(init: F) -> Lazy<T, F> {
743
0
            Lazy { cell: OnceCell::new(), init: Cell::new(Some(init)) }
744
0
        }
745
746
        /// Consumes this `Lazy` returning the stored value.
747
        ///
748
        /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
749
0
        pub fn into_value(this: Lazy<T, F>) -> Result<T, F> {
750
0
            let cell = this.cell;
751
0
            let init = this.init;
752
0
            cell.into_inner().ok_or_else(|| {
753
0
                init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned"))
754
0
            })
755
0
        }
756
    }
757
758
    impl<T, F: FnOnce() -> T> Lazy<T, F> {
759
        /// Forces the evaluation of this lazy value and returns a reference to
760
        /// the result.
761
        ///
762
        /// This is equivalent to the `Deref` impl, but is explicit.
763
        ///
764
        /// # Example
765
        /// ```
766
        /// use once_cell::unsync::Lazy;
767
        ///
768
        /// let lazy = Lazy::new(|| 92);
769
        ///
770
        /// assert_eq!(Lazy::force(&lazy), &92);
771
        /// assert_eq!(&*lazy, &92);
772
        /// ```
773
0
        pub fn force(this: &Lazy<T, F>) -> &T {
774
0
            this.cell.get_or_init(|| match this.init.take() {
775
0
                Some(f) => f(),
776
0
                None => panic!("Lazy instance has previously been poisoned"),
777
0
            })
778
0
        }
779
780
        /// Forces the evaluation of this lazy value and returns a mutable reference to
781
        /// the result.
782
        ///
783
        /// This is equivalent to the `DerefMut` impl, but is explicit.
784
        ///
785
        /// # Example
786
        /// ```
787
        /// use once_cell::unsync::Lazy;
788
        ///
789
        /// let mut lazy = Lazy::new(|| 92);
790
        ///
791
        /// assert_eq!(Lazy::force_mut(&mut lazy), &92);
792
        /// assert_eq!(*lazy, 92);
793
        /// ```
794
0
        pub fn force_mut(this: &mut Lazy<T, F>) -> &mut T {
795
0
            if this.cell.get_mut().is_none() {
796
0
                let value = match this.init.get_mut().take() {
797
0
                    Some(f) => f(),
798
0
                    None => panic!("Lazy instance has previously been poisoned"),
799
                };
800
0
                this.cell = OnceCell::with_value(value);
801
0
            }
802
0
            this.cell.get_mut().unwrap_or_else(|| unreachable!())
803
0
        }
804
805
        /// Gets the reference to the result of this lazy value if
806
        /// it was initialized, otherwise returns `None`.
807
        ///
808
        /// # Example
809
        /// ```
810
        /// use once_cell::unsync::Lazy;
811
        ///
812
        /// let lazy = Lazy::new(|| 92);
813
        ///
814
        /// assert_eq!(Lazy::get(&lazy), None);
815
        /// assert_eq!(&*lazy, &92);
816
        /// assert_eq!(Lazy::get(&lazy), Some(&92));
817
        /// ```
818
0
        pub fn get(this: &Lazy<T, F>) -> Option<&T> {
819
0
            this.cell.get()
820
0
        }
821
822
        /// Gets the mutable reference to the result of this lazy value if
823
        /// it was initialized, otherwise returns `None`.
824
        ///
825
        /// # Example
826
        /// ```
827
        /// use once_cell::unsync::Lazy;
828
        ///
829
        /// let mut lazy = Lazy::new(|| 92);
830
        ///
831
        /// assert_eq!(Lazy::get_mut(&mut lazy), None);
832
        /// assert_eq!(*lazy, 92);
833
        /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92));
834
        /// ```
835
0
        pub fn get_mut(this: &mut Lazy<T, F>) -> Option<&mut T> {
836
0
            this.cell.get_mut()
837
0
        }
838
    }
839
840
    impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
841
        type Target = T;
842
0
        fn deref(&self) -> &T {
843
0
            Lazy::force(self)
844
0
        }
845
    }
846
847
    impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
848
0
        fn deref_mut(&mut self) -> &mut T {
849
0
            Lazy::force_mut(self)
850
0
        }
851
    }
852
853
    impl<T: Default> Default for Lazy<T> {
854
        /// Creates a new lazy value using `Default` as the initializing function.
855
0
        fn default() -> Lazy<T> {
856
0
            Lazy::new(T::default)
857
0
        }
858
    }
859
}
860
861
/// Thread-safe, blocking version of `OnceCell`.
862
#[cfg(any(feature = "std", feature = "critical-section"))]
863
pub mod sync {
864
    use core::{
865
        cell::Cell,
866
        fmt, mem,
867
        ops::{Deref, DerefMut},
868
        panic::RefUnwindSafe,
869
    };
870
871
    use super::imp::OnceCell as Imp;
872
873
    /// A thread-safe cell which can be written to only once.
874
    ///
875
    /// `OnceCell` provides `&` references to the contents without RAII guards.
876
    ///
877
    /// Reading a non-`None` value out of `OnceCell` establishes a
878
    /// happens-before relationship with a corresponding write. For example, if
879
    /// thread A initializes the cell with `get_or_init(f)`, and thread B
880
    /// subsequently reads the result of this call, B also observes all the side
881
    /// effects of `f`.
882
    ///
883
    /// # Example
884
    /// ```
885
    /// use once_cell::sync::OnceCell;
886
    ///
887
    /// static CELL: OnceCell<String> = OnceCell::new();
888
    /// assert!(CELL.get().is_none());
889
    ///
890
    /// std::thread::spawn(|| {
891
    ///     let value: &String = CELL.get_or_init(|| {
892
    ///         "Hello, World!".to_string()
893
    ///     });
894
    ///     assert_eq!(value, "Hello, World!");
895
    /// }).join().unwrap();
896
    ///
897
    /// let value: Option<&String> = CELL.get();
898
    /// assert!(value.is_some());
899
    /// assert_eq!(value.unwrap().as_str(), "Hello, World!");
900
    /// ```
901
    pub struct OnceCell<T>(Imp<T>);
902
903
    impl<T> Default for OnceCell<T> {
904
0
        fn default() -> OnceCell<T> {
905
0
            OnceCell::new()
906
0
        }
907
    }
908
909
    impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
910
0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
911
0
            match self.get() {
912
0
                Some(v) => f.debug_tuple("OnceCell").field(v).finish(),
913
0
                None => f.write_str("OnceCell(Uninit)"),
914
            }
915
0
        }
916
    }
917
918
    impl<T: Clone> Clone for OnceCell<T> {
919
0
        fn clone(&self) -> OnceCell<T> {
920
0
            match self.get() {
921
0
                Some(value) => Self::with_value(value.clone()),
922
0
                None => Self::new(),
923
            }
924
0
        }
925
926
0
        fn clone_from(&mut self, source: &Self) {
927
0
            match (self.get_mut(), source.get()) {
928
0
                (Some(this), Some(source)) => this.clone_from(source),
929
0
                _ => *self = source.clone(),
930
            }
931
0
        }
932
    }
933
934
    impl<T> From<T> for OnceCell<T> {
935
0
        fn from(value: T) -> Self {
936
0
            Self::with_value(value)
937
0
        }
938
    }
939
940
    impl<T: PartialEq> PartialEq for OnceCell<T> {
941
0
        fn eq(&self, other: &OnceCell<T>) -> bool {
942
0
            self.get() == other.get()
943
0
        }
944
    }
945
946
    impl<T: Eq> Eq for OnceCell<T> {}
947
948
    impl<T> OnceCell<T> {
949
        /// Creates a new empty cell.
950
0
        pub const fn new() -> OnceCell<T> {
951
0
            OnceCell(Imp::new())
952
0
        }
953
954
        /// Creates a new initialized cell.
955
0
        pub const fn with_value(value: T) -> OnceCell<T> {
956
0
            OnceCell(Imp::with_value(value))
957
0
        }
958
959
        /// Gets the reference to the underlying value.
960
        ///
961
        /// Returns `None` if the cell is empty, or being initialized. This
962
        /// method never blocks.
963
5.67k
        pub fn get(&self) -> Option<&T> {
964
5.67k
            if self.0.is_initialized() {
965
                // Safe b/c value is initialized.
966
0
                Some(unsafe { self.get_unchecked() })
967
            } else {
968
5.67k
                None
969
            }
970
5.67k
        }
_RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE3getCs5HNiFFfDLPG_6decode
Line
Count
Source
963
5.67k
        pub fn get(&self) -> Option<&T> {
964
5.67k
            if self.0.is_initialized() {
965
                // Safe b/c value is initialized.
966
0
                Some(unsafe { self.get_unchecked() })
967
            } else {
968
5.67k
                None
969
            }
970
5.67k
        }
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE3getCs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellpE3getB7_
971
972
        /// Gets the reference to the underlying value, blocking the current
973
        /// thread until it is set.
974
        ///
975
        /// ```
976
        /// use once_cell::sync::OnceCell;
977
        ///
978
        /// let mut cell = std::sync::Arc::new(OnceCell::new());
979
        /// let t = std::thread::spawn({
980
        ///     let cell = std::sync::Arc::clone(&cell);
981
        ///     move || cell.set(92).unwrap()
982
        /// });
983
        ///
984
        /// // Returns immediately, but might return None.
985
        /// let _value_or_none = cell.get();
986
        ///
987
        /// // Will return 92, but might block until the other thread does `.set`.
988
        /// let value: &u32 = cell.wait();
989
        /// assert_eq!(*value, 92);
990
        /// t.join().unwrap();
991
        /// ```
992
        #[cfg(feature = "std")]
993
0
        pub fn wait(&self) -> &T {
994
0
            if !self.0.is_initialized() {
995
0
                self.0.wait()
996
0
            }
997
0
            debug_assert!(self.0.is_initialized());
998
            // Safe b/c of the wait call above and the fact that we didn't
999
            // relinquish our borrow.
1000
0
            unsafe { self.get_unchecked() }
1001
0
        }
1002
1003
        /// Gets the mutable reference to the underlying value.
1004
        ///
1005
        /// Returns `None` if the cell is empty.
1006
        ///
1007
        /// This method is allowed to violate the invariant of writing to a `OnceCell`
1008
        /// at most once because it requires `&mut` access to `self`. As with all
1009
        /// interior mutability, `&mut` access permits arbitrary modification:
1010
        ///
1011
        /// ```
1012
        /// use once_cell::sync::OnceCell;
1013
        ///
1014
        /// let mut cell: OnceCell<u32> = OnceCell::new();
1015
        /// cell.set(92).unwrap();
1016
        /// cell = OnceCell::new();
1017
        /// ```
1018
        #[inline]
1019
0
        pub fn get_mut(&mut self) -> Option<&mut T> {
1020
0
            self.0.get_mut()
1021
0
        }
1022
1023
        /// Get the reference to the underlying value, without checking if the
1024
        /// cell is initialized.
1025
        ///
1026
        /// # Safety
1027
        ///
1028
        /// Caller must ensure that the cell is in initialized state, and that
1029
        /// the contents are acquired by (synchronized to) this thread.
1030
        #[inline]
1031
0
        pub unsafe fn get_unchecked(&self) -> &T {
1032
0
            self.0.get_unchecked()
1033
0
        }
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE13get_uncheckedCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE13get_uncheckedCs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellpE13get_uncheckedB7_
1034
1035
        /// Sets the contents of this cell to `value`.
1036
        ///
1037
        /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
1038
        /// full.
1039
        ///
1040
        /// # Example
1041
        ///
1042
        /// ```
1043
        /// use once_cell::sync::OnceCell;
1044
        ///
1045
        /// static CELL: OnceCell<i32> = OnceCell::new();
1046
        ///
1047
        /// fn main() {
1048
        ///     assert!(CELL.get().is_none());
1049
        ///
1050
        ///     std::thread::spawn(|| {
1051
        ///         assert_eq!(CELL.set(92), Ok(()));
1052
        ///     }).join().unwrap();
1053
        ///
1054
        ///     assert_eq!(CELL.set(62), Err(62));
1055
        ///     assert_eq!(CELL.get(), Some(&92));
1056
        /// }
1057
        /// ```
1058
0
        pub fn set(&self, value: T) -> Result<(), T> {
1059
0
            match self.try_insert(value) {
1060
0
                Ok(_) => Ok(()),
1061
0
                Err((_, value)) => Err(value),
1062
            }
1063
0
        }
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE3setCs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellpE3setB7_
1064
1065
        /// Like [`set`](Self::set), but also returns a reference to the final cell value.
1066
        ///
1067
        /// # Example
1068
        ///
1069
        /// ```
1070
        /// use once_cell::unsync::OnceCell;
1071
        ///
1072
        /// let cell = OnceCell::new();
1073
        /// assert!(cell.get().is_none());
1074
        ///
1075
        /// assert_eq!(cell.try_insert(92), Ok(&92));
1076
        /// assert_eq!(cell.try_insert(62), Err((&92, 62)));
1077
        ///
1078
        /// assert!(cell.get().is_some());
1079
        /// ```
1080
0
        pub fn try_insert(&self, value: T) -> Result<&T, (&T, T)> {
1081
0
            let mut value = Some(value);
1082
0
            let res = self.get_or_init(|| unsafe { value.take().unwrap_unchecked() });
Unexecuted instantiation: _RNCNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB7_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE10try_insert0Cs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNCNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB7_8OnceCellpE10try_insert0B9_
1083
0
            match value {
1084
0
                None => Ok(res),
1085
0
                Some(value) => Err((res, value)),
1086
            }
1087
0
        }
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE10try_insertCs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB5_8OnceCellpE10try_insertB7_
1088
1089
        /// Gets the contents of the cell, initializing it with `f` if the cell
1090
        /// was empty.
1091
        ///
1092
        /// Many threads may call `get_or_init` concurrently with different
1093
        /// initializing functions, but it is guaranteed that only one function
1094
        /// will be executed.
1095
        ///
1096
        /// # Panics
1097
        ///
1098
        /// If `f` panics, the panic is propagated to the caller, and the cell
1099
        /// remains uninitialized.
1100
        ///
1101
        /// It is an error to reentrantly initialize the cell from `f`. The
1102
        /// exact outcome is unspecified. Current implementation deadlocks, but
1103
        /// this may be changed to a panic in the future.
1104
        ///
1105
        /// # Example
1106
        /// ```
1107
        /// use once_cell::sync::OnceCell;
1108
        ///
1109
        /// let cell = OnceCell::new();
1110
        /// let value = cell.get_or_init(|| 92);
1111
        /// assert_eq!(value, &92);
1112
        /// let value = cell.get_or_init(|| unreachable!());
1113
        /// assert_eq!(value, &92);
1114
        /// ```
1115
0
        pub fn get_or_init<F>(&self, f: F) -> &T
1116
0
        where
1117
0
            F: FnOnce() -> T,
1118
0
        {
1119
0
            enum Void {}
1120
0
            match self.get_or_try_init(|| Ok::<T, Void>(f())) {
Unexecuted instantiation: _RNCINvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB8_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE11get_or_initNCNvB4_10try_insert0E0Cs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RNCINvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB8_8OnceCellpE11get_or_initpE0Ba_
1121
0
                Ok(val) => val,
1122
0
                Err(void) => match void {},
1123
0
            }
1124
0
        }
Unexecuted instantiation: _RINvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB6_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE11get_or_initNCNvB2_10try_insert0ECs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RINvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB6_8OnceCellpE11get_or_initpEB8_
1125
1126
        /// Gets the contents of the cell, initializing it with `f` if
1127
        /// the cell was empty. If the cell was empty and `f` failed, an
1128
        /// error is returned.
1129
        ///
1130
        /// # Panics
1131
        ///
1132
        /// If `f` panics, the panic is propagated to the caller, and
1133
        /// the cell remains uninitialized.
1134
        ///
1135
        /// It is an error to reentrantly initialize the cell from `f`.
1136
        /// The exact outcome is unspecified. Current implementation
1137
        /// deadlocks, but this may be changed to a panic in the future.
1138
        ///
1139
        /// # Example
1140
        /// ```
1141
        /// use once_cell::sync::OnceCell;
1142
        ///
1143
        /// let cell = OnceCell::new();
1144
        /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
1145
        /// assert!(cell.get().is_none());
1146
        /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
1147
        ///     Ok(92)
1148
        /// });
1149
        /// assert_eq!(value, Ok(&92));
1150
        /// assert_eq!(cell.get(), Some(&92))
1151
        /// ```
1152
0
        pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
1153
0
        where
1154
0
            F: FnOnce() -> Result<T, E>,
1155
0
        {
1156
            // Fast path check
1157
0
            if let Some(value) = self.get() {
1158
0
                return Ok(value);
1159
0
            }
1160
0
1161
0
            self.0.initialize(f)?;
1162
1163
            // Safe b/c value is initialized.
1164
0
            debug_assert!(self.0.is_initialized());
1165
0
            Ok(unsafe { self.get_unchecked() })
1166
0
        }
Unexecuted instantiation: _RINvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB6_8OnceCellNtNtCsbpSlAbJY2yh_5alloc6string6StringE15get_or_try_initNCINvB2_11get_or_initNCNvB2_10try_insert0E0NtNvMs4_B6_IBC_pE11get_or_init4VoidECs32fhybPB127_13libfuzzer_sys
Unexecuted instantiation: _RINvMs4_NtCsieqz2xIPOqY_9once_cell4syncINtB6_8OnceCellpE15get_or_try_initppEB8_
1167
1168
        /// Takes the value out of this `OnceCell`, moving it back to an uninitialized state.
1169
        ///
1170
        /// Has no effect and returns `None` if the `OnceCell` hasn't been initialized.
1171
        ///
1172
        /// # Examples
1173
        ///
1174
        /// ```
1175
        /// use once_cell::sync::OnceCell;
1176
        ///
1177
        /// let mut cell: OnceCell<String> = OnceCell::new();
1178
        /// assert_eq!(cell.take(), None);
1179
        ///
1180
        /// let mut cell = OnceCell::new();
1181
        /// cell.set("hello".to_string()).unwrap();
1182
        /// assert_eq!(cell.take(), Some("hello".to_string()));
1183
        /// assert_eq!(cell.get(), None);
1184
        /// ```
1185
        ///
1186
        /// This method is allowed to violate the invariant of writing to a `OnceCell`
1187
        /// at most once because it requires `&mut` access to `self`. As with all
1188
        /// interior mutability, `&mut` access permits arbitrary modification:
1189
        ///
1190
        /// ```
1191
        /// use once_cell::sync::OnceCell;
1192
        ///
1193
        /// let mut cell: OnceCell<u32> = OnceCell::new();
1194
        /// cell.set(92).unwrap();
1195
        /// cell = OnceCell::new();
1196
        /// ```
1197
0
        pub fn take(&mut self) -> Option<T> {
1198
0
            mem::take(self).into_inner()
1199
0
        }
1200
1201
        /// Consumes the `OnceCell`, returning the wrapped value. Returns
1202
        /// `None` if the cell was empty.
1203
        ///
1204
        /// # Examples
1205
        ///
1206
        /// ```
1207
        /// use once_cell::sync::OnceCell;
1208
        ///
1209
        /// let cell: OnceCell<String> = OnceCell::new();
1210
        /// assert_eq!(cell.into_inner(), None);
1211
        ///
1212
        /// let cell = OnceCell::new();
1213
        /// cell.set("hello".to_string()).unwrap();
1214
        /// assert_eq!(cell.into_inner(), Some("hello".to_string()));
1215
        /// ```
1216
        #[inline]
1217
0
        pub fn into_inner(self) -> Option<T> {
1218
0
            self.0.into_inner()
1219
0
        }
1220
    }
1221
1222
    /// A value which is initialized on the first access.
1223
    ///
1224
    /// This type is thread-safe and can be used in statics.
1225
    ///
1226
    /// # Example
1227
    ///
1228
    /// ```
1229
    /// use std::collections::HashMap;
1230
    ///
1231
    /// use once_cell::sync::Lazy;
1232
    ///
1233
    /// static HASHMAP: Lazy<HashMap<i32, String>> = Lazy::new(|| {
1234
    ///     println!("initializing");
1235
    ///     let mut m = HashMap::new();
1236
    ///     m.insert(13, "Spica".to_string());
1237
    ///     m.insert(74, "Hoyten".to_string());
1238
    ///     m
1239
    /// });
1240
    ///
1241
    /// fn main() {
1242
    ///     println!("ready");
1243
    ///     std::thread::spawn(|| {
1244
    ///         println!("{:?}", HASHMAP.get(&13));
1245
    ///     }).join().unwrap();
1246
    ///     println!("{:?}", HASHMAP.get(&74));
1247
    ///
1248
    ///     // Prints:
1249
    ///     //   ready
1250
    ///     //   initializing
1251
    ///     //   Some("Spica")
1252
    ///     //   Some("Hoyten")
1253
    /// }
1254
    /// ```
1255
    pub struct Lazy<T, F = fn() -> T> {
1256
        cell: OnceCell<T>,
1257
        init: Cell<Option<F>>,
1258
    }
1259
1260
    impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
1261
0
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1262
0
            f.debug_struct("Lazy").field("cell", &self.cell).field("init", &"..").finish()
1263
0
        }
1264
    }
1265
1266
    // We never create a `&F` from a `&Lazy<T, F>` so it is fine to not impl
1267
    // `Sync` for `F`. We do create a `&mut Option<F>` in `force`, but this is
1268
    // properly synchronized, so it only happens once so it also does not
1269
    // contribute to this impl.
1270
    unsafe impl<T, F: Send> Sync for Lazy<T, F> where OnceCell<T>: Sync {}
1271
    // auto-derived `Send` impl is OK.
1272
1273
    impl<T, F: RefUnwindSafe> RefUnwindSafe for Lazy<T, F> where OnceCell<T>: RefUnwindSafe {}
1274
1275
    impl<T, F> Lazy<T, F> {
1276
        /// Creates a new lazy value with the given initializing
1277
        /// function.
1278
0
        pub const fn new(f: F) -> Lazy<T, F> {
1279
0
            Lazy { cell: OnceCell::new(), init: Cell::new(Some(f)) }
1280
0
        }
1281
1282
        /// Consumes this `Lazy` returning the stored value.
1283
        ///
1284
        /// Returns `Ok(value)` if `Lazy` is initialized and `Err(f)` otherwise.
1285
0
        pub fn into_value(this: Lazy<T, F>) -> Result<T, F> {
1286
0
            let cell = this.cell;
1287
0
            let init = this.init;
1288
0
            cell.into_inner().ok_or_else(|| {
1289
0
                init.take().unwrap_or_else(|| panic!("Lazy instance has previously been poisoned"))
1290
0
            })
1291
0
        }
1292
    }
1293
1294
    impl<T, F: FnOnce() -> T> Lazy<T, F> {
1295
        /// Forces the evaluation of this lazy value and
1296
        /// returns a reference to the result. This is equivalent
1297
        /// to the `Deref` impl, but is explicit.
1298
        ///
1299
        /// # Example
1300
        /// ```
1301
        /// use once_cell::sync::Lazy;
1302
        ///
1303
        /// let lazy = Lazy::new(|| 92);
1304
        ///
1305
        /// assert_eq!(Lazy::force(&lazy), &92);
1306
        /// assert_eq!(&*lazy, &92);
1307
        /// ```
1308
0
        pub fn force(this: &Lazy<T, F>) -> &T {
1309
0
            this.cell.get_or_init(|| match this.init.take() {
1310
0
                Some(f) => f(),
1311
0
                None => panic!("Lazy instance has previously been poisoned"),
1312
0
            })
1313
0
        }
1314
1315
        /// Forces the evaluation of this lazy value and
1316
        /// returns a mutable reference to the result. This is equivalent
1317
        /// to the `Deref` impl, but is explicit.
1318
        ///
1319
        /// # Example
1320
        /// ```
1321
        /// use once_cell::sync::Lazy;
1322
        ///
1323
        /// let mut lazy = Lazy::new(|| 92);
1324
        ///
1325
        /// assert_eq!(Lazy::force_mut(&mut lazy), &mut 92);
1326
        /// ```
1327
0
        pub fn force_mut(this: &mut Lazy<T, F>) -> &mut T {
1328
0
            if this.cell.get_mut().is_none() {
1329
0
                let value = match this.init.get_mut().take() {
1330
0
                    Some(f) => f(),
1331
0
                    None => panic!("Lazy instance has previously been poisoned"),
1332
                };
1333
0
                this.cell = OnceCell::with_value(value);
1334
0
            }
1335
0
            this.cell.get_mut().unwrap_or_else(|| unreachable!())
1336
0
        }
1337
1338
        /// Gets the reference to the result of this lazy value if
1339
        /// it was initialized, otherwise returns `None`.
1340
        ///
1341
        /// # Example
1342
        /// ```
1343
        /// use once_cell::sync::Lazy;
1344
        ///
1345
        /// let lazy = Lazy::new(|| 92);
1346
        ///
1347
        /// assert_eq!(Lazy::get(&lazy), None);
1348
        /// assert_eq!(&*lazy, &92);
1349
        /// assert_eq!(Lazy::get(&lazy), Some(&92));
1350
        /// ```
1351
0
        pub fn get(this: &Lazy<T, F>) -> Option<&T> {
1352
0
            this.cell.get()
1353
0
        }
1354
1355
        /// Gets the reference to the result of this lazy value if
1356
        /// it was initialized, otherwise returns `None`.
1357
        ///
1358
        /// # Example
1359
        /// ```
1360
        /// use once_cell::sync::Lazy;
1361
        ///
1362
        /// let mut lazy = Lazy::new(|| 92);
1363
        ///
1364
        /// assert_eq!(Lazy::get_mut(&mut lazy), None);
1365
        /// assert_eq!(&*lazy, &92);
1366
        /// assert_eq!(Lazy::get_mut(&mut lazy), Some(&mut 92));
1367
        /// ```
1368
0
        pub fn get_mut(this: &mut Lazy<T, F>) -> Option<&mut T> {
1369
0
            this.cell.get_mut()
1370
0
        }
1371
    }
1372
1373
    impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
1374
        type Target = T;
1375
0
        fn deref(&self) -> &T {
1376
0
            Lazy::force(self)
1377
0
        }
1378
    }
1379
1380
    impl<T, F: FnOnce() -> T> DerefMut for Lazy<T, F> {
1381
0
        fn deref_mut(&mut self) -> &mut T {
1382
0
            Lazy::force_mut(self)
1383
0
        }
1384
    }
1385
1386
    impl<T: Default> Default for Lazy<T> {
1387
        /// Creates a new lazy value using `Default` as the initializing function.
1388
0
        fn default() -> Lazy<T> {
1389
0
            Lazy::new(T::default)
1390
0
        }
1391
    }
1392
1393
    /// ```compile_fail
1394
    /// struct S(*mut ());
1395
    /// unsafe impl Sync for S {}
1396
    ///
1397
    /// fn share<T: Sync>(_: &T) {}
1398
    /// share(&once_cell::sync::OnceCell::<S>::new());
1399
    /// ```
1400
    ///
1401
    /// ```compile_fail
1402
    /// struct S(*mut ());
1403
    /// unsafe impl Sync for S {}
1404
    ///
1405
    /// fn share<T: Sync>(_: &T) {}
1406
    /// share(&once_cell::sync::Lazy::<S>::new(|| unimplemented!()));
1407
    /// ```
1408
0
    fn _dummy() {}
1409
}
1410
1411
#[cfg(feature = "race")]
1412
pub mod race;
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/once_cell-1.19.0/src/race.rs
Line
Count
Source (jump to first uncovered line)
1
//! Thread-safe, non-blocking, "first one wins" flavor of `OnceCell`.
2
//!
3
//! If two threads race to initialize a type from the `race` module, they
4
//! don't block, execute initialization function together, but only one of
5
//! them stores the result.
6
//!
7
//! This module does not require `std` feature.
8
//!
9
//! # Atomic orderings
10
//!
11
//! All types in this module use `Acquire` and `Release`
12
//! [atomic orderings](Ordering) for all their operations. While this is not
13
//! strictly necessary for types other than `OnceBox`, it is useful for users as
14
//! it allows them to be certain that after `get` or `get_or_init` returns on
15
//! one thread, any side-effects caused by the setter thread prior to them
16
//! calling `set` or `get_or_init` will be made visible to that thread; without
17
//! it, it's possible for it to appear as if they haven't happened yet from the
18
//! getter thread's perspective. This is an acceptable tradeoff to make since
19
//! `Acquire` and `Release` have very little performance overhead on most
20
//! architectures versus `Relaxed`.
21
22
#[cfg(feature = "critical-section")]
23
use portable_atomic as atomic;
24
#[cfg(not(feature = "critical-section"))]
25
use core::sync::atomic;
26
27
use atomic::{AtomicPtr, AtomicUsize, Ordering};
28
use core::cell::UnsafeCell;
29
use core::marker::PhantomData;
30
use core::num::NonZeroUsize;
31
use core::ptr;
32
33
/// A thread-safe cell which can be written to only once.
34
#[derive(Default, Debug)]
35
pub struct OnceNonZeroUsize {
36
    inner: AtomicUsize,
37
}
38
39
impl OnceNonZeroUsize {
40
    /// Creates a new empty cell.
41
    #[inline]
42
0
    pub const fn new() -> OnceNonZeroUsize {
43
0
        OnceNonZeroUsize { inner: AtomicUsize::new(0) }
44
0
    }
45
46
    /// Gets the underlying value.
47
    #[inline]
48
0
    pub fn get(&self) -> Option<NonZeroUsize> {
49
0
        let val = self.inner.load(Ordering::Acquire);
50
0
        NonZeroUsize::new(val)
51
0
    }
52
53
    /// Sets the contents of this cell to `value`.
54
    ///
55
    /// Returns `Ok(())` if the cell was empty and `Err(())` if it was
56
    /// full.
57
    #[inline]
58
0
    pub fn set(&self, value: NonZeroUsize) -> Result<(), ()> {
59
0
        let exchange =
60
0
            self.inner.compare_exchange(0, value.get(), Ordering::AcqRel, Ordering::Acquire);
61
0
        match exchange {
62
0
            Ok(_) => Ok(()),
63
0
            Err(_) => Err(()),
64
        }
65
0
    }
66
67
    /// Gets the contents of the cell, initializing it with `f` if the cell was
68
    /// empty.
69
    ///
70
    /// If several threads concurrently run `get_or_init`, more than one `f` can
71
    /// be called. However, all threads will return the same value, produced by
72
    /// some `f`.
73
0
    pub fn get_or_init<F>(&self, f: F) -> NonZeroUsize
74
0
    where
75
0
        F: FnOnce() -> NonZeroUsize,
76
0
    {
77
0
        enum Void {}
78
0
        match self.get_or_try_init(|| Ok::<NonZeroUsize, Void>(f())) {
79
0
            Ok(val) => val,
80
0
            Err(void) => match void {},
81
0
        }
82
0
    }
83
84
    /// Gets the contents of the cell, initializing it with `f` if
85
    /// the cell was empty. If the cell was empty and `f` failed, an
86
    /// error is returned.
87
    ///
88
    /// If several threads concurrently run `get_or_init`, more than one `f` can
89
    /// be called. However, all threads will return the same value, produced by
90
    /// some `f`.
91
0
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<NonZeroUsize, E>
92
0
    where
93
0
        F: FnOnce() -> Result<NonZeroUsize, E>,
94
0
    {
95
0
        let val = self.inner.load(Ordering::Acquire);
96
0
        let res = match NonZeroUsize::new(val) {
97
0
            Some(it) => it,
98
            None => {
99
0
                let mut val = f()?.get();
100
0
                let exchange =
101
0
                    self.inner.compare_exchange(0, val, Ordering::AcqRel, Ordering::Acquire);
102
0
                if let Err(old) = exchange {
103
0
                    val = old;
104
0
                }
105
0
                unsafe { NonZeroUsize::new_unchecked(val) }
106
            }
107
        };
108
0
        Ok(res)
109
0
    }
110
}
111
112
/// A thread-safe cell which can be written to only once.
113
#[derive(Default, Debug)]
114
pub struct OnceBool {
115
    inner: OnceNonZeroUsize,
116
}
117
118
impl OnceBool {
119
    /// Creates a new empty cell.
120
    #[inline]
121
0
    pub const fn new() -> OnceBool {
122
0
        OnceBool { inner: OnceNonZeroUsize::new() }
123
0
    }
124
125
    /// Gets the underlying value.
126
    #[inline]
127
0
    pub fn get(&self) -> Option<bool> {
128
0
        self.inner.get().map(OnceBool::from_usize)
129
0
    }
130
131
    /// Sets the contents of this cell to `value`.
132
    ///
133
    /// Returns `Ok(())` if the cell was empty and `Err(())` if it was
134
    /// full.
135
    #[inline]
136
0
    pub fn set(&self, value: bool) -> Result<(), ()> {
137
0
        self.inner.set(OnceBool::to_usize(value))
138
0
    }
139
140
    /// Gets the contents of the cell, initializing it with `f` if the cell was
141
    /// empty.
142
    ///
143
    /// If several threads concurrently run `get_or_init`, more than one `f` can
144
    /// be called. However, all threads will return the same value, produced by
145
    /// some `f`.
146
0
    pub fn get_or_init<F>(&self, f: F) -> bool
147
0
    where
148
0
        F: FnOnce() -> bool,
149
0
    {
150
0
        OnceBool::from_usize(self.inner.get_or_init(|| OnceBool::to_usize(f())))
151
0
    }
152
153
    /// Gets the contents of the cell, initializing it with `f` if
154
    /// the cell was empty. If the cell was empty and `f` failed, an
155
    /// error is returned.
156
    ///
157
    /// If several threads concurrently run `get_or_init`, more than one `f` can
158
    /// be called. However, all threads will return the same value, produced by
159
    /// some `f`.
160
0
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<bool, E>
161
0
    where
162
0
        F: FnOnce() -> Result<bool, E>,
163
0
    {
164
0
        self.inner.get_or_try_init(|| f().map(OnceBool::to_usize)).map(OnceBool::from_usize)
165
0
    }
166
167
    #[inline]
168
0
    fn from_usize(value: NonZeroUsize) -> bool {
169
0
        value.get() == 1
170
0
    }
171
172
    #[inline]
173
0
    fn to_usize(value: bool) -> NonZeroUsize {
174
0
        unsafe { NonZeroUsize::new_unchecked(if value { 1 } else { 2 }) }
175
0
    }
176
}
177
178
/// A thread-safe cell which can be written to only once.
179
pub struct OnceRef<'a, T> {
180
    inner: AtomicPtr<T>,
181
    ghost: PhantomData<UnsafeCell<&'a T>>,
182
}
183
184
// TODO: Replace UnsafeCell with SyncUnsafeCell once stabilized
185
unsafe impl<'a, T: Sync> Sync for OnceRef<'a, T> {}
186
187
impl<'a, T> core::fmt::Debug for OnceRef<'a, T> {
188
0
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
189
0
        write!(f, "OnceRef({:?})", self.inner)
190
0
    }
191
}
192
193
impl<'a, T> Default for OnceRef<'a, T> {
194
0
    fn default() -> Self {
195
0
        Self::new()
196
0
    }
197
}
198
199
impl<'a, T> OnceRef<'a, T> {
200
    /// Creates a new empty cell.
201
0
    pub const fn new() -> OnceRef<'a, T> {
202
0
        OnceRef { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData }
203
0
    }
204
205
    /// Gets a reference to the underlying value.
206
0
    pub fn get(&self) -> Option<&'a T> {
207
0
        let ptr = self.inner.load(Ordering::Acquire);
208
0
        unsafe { ptr.as_ref() }
209
0
    }
210
211
    /// Sets the contents of this cell to `value`.
212
    ///
213
    /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
214
    /// full.
215
0
    pub fn set(&self, value: &'a T) -> Result<(), ()> {
216
0
        let ptr = value as *const T as *mut T;
217
0
        let exchange =
218
0
            self.inner.compare_exchange(ptr::null_mut(), ptr, Ordering::AcqRel, Ordering::Acquire);
219
0
        match exchange {
220
0
            Ok(_) => Ok(()),
221
0
            Err(_) => Err(()),
222
        }
223
0
    }
224
225
    /// Gets the contents of the cell, initializing it with `f` if the cell was
226
    /// empty.
227
    ///
228
    /// If several threads concurrently run `get_or_init`, more than one `f` can
229
    /// be called. However, all threads will return the same value, produced by
230
    /// some `f`.
231
0
    pub fn get_or_init<F>(&self, f: F) -> &'a T
232
0
    where
233
0
        F: FnOnce() -> &'a T,
234
0
    {
235
0
        enum Void {}
236
0
        match self.get_or_try_init(|| Ok::<&'a T, Void>(f())) {
237
0
            Ok(val) => val,
238
0
            Err(void) => match void {},
239
0
        }
240
0
    }
241
242
    /// Gets the contents of the cell, initializing it with `f` if
243
    /// the cell was empty. If the cell was empty and `f` failed, an
244
    /// error is returned.
245
    ///
246
    /// If several threads concurrently run `get_or_init`, more than one `f` can
247
    /// be called. However, all threads will return the same value, produced by
248
    /// some `f`.
249
0
    pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&'a T, E>
250
0
    where
251
0
        F: FnOnce() -> Result<&'a T, E>,
252
0
    {
253
0
        let mut ptr = self.inner.load(Ordering::Acquire);
254
0
255
0
        if ptr.is_null() {
256
            // TODO replace with `cast_mut` when MSRV reaches 1.65.0 (also in `set`)
257
0
            ptr = f()? as *const T as *mut T;
258
0
            let exchange = self.inner.compare_exchange(
259
0
                ptr::null_mut(),
260
0
                ptr,
261
0
                Ordering::AcqRel,
262
0
                Ordering::Acquire,
263
0
            );
264
0
            if let Err(old) = exchange {
265
0
                ptr = old;
266
0
            }
267
0
        }
268
269
0
        Ok(unsafe { &*ptr })
270
0
    }
271
272
    /// ```compile_fail
273
    /// use once_cell::race::OnceRef;
274
    ///
275
    /// let mut l = OnceRef::new();
276
    ///
277
    /// {
278
    ///     let y = 2;
279
    ///     let mut r = OnceRef::new();
280
    ///     r.set(&y).unwrap();
281
    ///     core::mem::swap(&mut l, &mut r);
282
    /// }
283
    ///
284
    /// // l now contains a dangling reference to y
285
    /// eprintln!("uaf: {}", l.get().unwrap());
286
    /// ```
287
0
    fn _dummy() {}
288
}
289
290
#[cfg(feature = "alloc")]
291
pub use self::once_box::OnceBox;
292
293
#[cfg(feature = "alloc")]
294
mod once_box {
295
    use super::atomic::{AtomicPtr, Ordering};
296
    use core::{marker::PhantomData, ptr};
297
298
    use alloc::boxed::Box;
299
300
    /// A thread-safe cell which can be written to only once.
301
    pub struct OnceBox<T> {
302
        inner: AtomicPtr<T>,
303
        ghost: PhantomData<Option<Box<T>>>,
304
    }
305
306
    impl<T> core::fmt::Debug for OnceBox<T> {
307
0
        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
308
0
            write!(f, "OnceBox({:?})", self.inner.load(Ordering::Relaxed))
309
0
        }
310
    }
311
312
    impl<T> Default for OnceBox<T> {
313
0
        fn default() -> Self {
314
0
            Self::new()
315
0
        }
316
    }
317
318
    impl<T> Drop for OnceBox<T> {
319
0
        fn drop(&mut self) {
320
0
            let ptr = *self.inner.get_mut();
321
0
            if !ptr.is_null() {
322
0
                drop(unsafe { Box::from_raw(ptr) })
323
0
            }
324
0
        }
325
    }
326
327
    impl<T> OnceBox<T> {
328
        /// Creates a new empty cell.
329
0
        pub const fn new() -> OnceBox<T> {
330
0
            OnceBox { inner: AtomicPtr::new(ptr::null_mut()), ghost: PhantomData }
331
0
        }
332
333
        /// Gets a reference to the underlying value.
334
0
        pub fn get(&self) -> Option<&T> {
335
0
            let ptr = self.inner.load(Ordering::Acquire);
336
0
            if ptr.is_null() {
337
0
                return None;
338
0
            }
339
0
            Some(unsafe { &*ptr })
340
0
        }
341
342
        /// Sets the contents of this cell to `value`.
343
        ///
344
        /// Returns `Ok(())` if the cell was empty and `Err(value)` if it was
345
        /// full.
346
0
        pub fn set(&self, value: Box<T>) -> Result<(), Box<T>> {
347
0
            let ptr = Box::into_raw(value);
348
0
            let exchange = self.inner.compare_exchange(
349
0
                ptr::null_mut(),
350
0
                ptr,
351
0
                Ordering::AcqRel,
352
0
                Ordering::Acquire,
353
0
            );
354
0
            if exchange.is_err() {
355
0
                let value = unsafe { Box::from_raw(ptr) };
356
0
                return Err(value);
357
0
            }
358
0
            Ok(())
359
0
        }
360
361
        /// Gets the contents of the cell, initializing it with `f` if the cell was
362
        /// empty.
363
        ///
364
        /// If several threads concurrently run `get_or_init`, more than one `f` can
365
        /// be called. However, all threads will return the same value, produced by
366
        /// some `f`.
367
0
        pub fn get_or_init<F>(&self, f: F) -> &T
368
0
        where
369
0
            F: FnOnce() -> Box<T>,
370
0
        {
371
0
            enum Void {}
372
0
            match self.get_or_try_init(|| Ok::<Box<T>, Void>(f())) {
373
0
                Ok(val) => val,
374
0
                Err(void) => match void {},
375
0
            }
376
0
        }
377
378
        /// Gets the contents of the cell, initializing it with `f` if
379
        /// the cell was empty. If the cell was empty and `f` failed, an
380
        /// error is returned.
381
        ///
382
        /// If several threads concurrently run `get_or_init`, more than one `f` can
383
        /// be called. However, all threads will return the same value, produced by
384
        /// some `f`.
385
0
        pub fn get_or_try_init<F, E>(&self, f: F) -> Result<&T, E>
386
0
        where
387
0
            F: FnOnce() -> Result<Box<T>, E>,
388
0
        {
389
0
            let mut ptr = self.inner.load(Ordering::Acquire);
390
0
391
0
            if ptr.is_null() {
392
0
                let val = f()?;
393
0
                ptr = Box::into_raw(val);
394
0
                let exchange = self.inner.compare_exchange(
395
0
                    ptr::null_mut(),
396
0
                    ptr,
397
0
                    Ordering::AcqRel,
398
0
                    Ordering::Acquire,
399
0
                );
400
0
                if let Err(old) = exchange {
401
0
                    drop(unsafe { Box::from_raw(ptr) });
402
0
                    ptr = old;
403
0
                }
404
0
            };
405
0
            Ok(unsafe { &*ptr })
406
0
        }
407
    }
408
409
    unsafe impl<T: Sync + Send> Sync for OnceBox<T> {}
410
411
    /// ```compile_fail
412
    /// struct S(*mut ());
413
    /// unsafe impl Sync for S {}
414
    ///
415
    /// fn share<T: Sync>(_: &T) {}
416
    /// share(&once_cell::race::OnceBox::<S>::new());
417
    /// ```
418
0
    fn _dummy() {}
419
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/thiserror-1.0.61/src/display.rs
Line
Count
Source (jump to first uncovered line)
1
use core::fmt::Display;
2
use std::path::{self, Path, PathBuf};
3
4
#[doc(hidden)]
5
pub trait AsDisplay<'a> {
6
    // TODO: convert to generic associated type.
7
    // https://github.com/dtolnay/thiserror/pull/253
8
    type Target: Display;
9
10
    fn as_display(&'a self) -> Self::Target;
11
}
12
13
impl<'a, T> AsDisplay<'a> for &T
14
where
15
    T: Display + 'a,
16
{
17
    type Target = &'a T;
18
19
0
    fn as_display(&'a self) -> Self::Target {
20
0
        *self
21
0
    }
22
}
23
24
impl<'a> AsDisplay<'a> for Path {
25
    type Target = path::Display<'a>;
26
27
    #[inline]
28
    fn as_display(&'a self) -> Self::Target {
29
        self.display()
30
    }
31
}
32
33
impl<'a> AsDisplay<'a> for PathBuf {
34
    type Target = path::Display<'a>;
35
36
    #[inline]
37
    fn as_display(&'a self) -> Self::Target {
38
        self.display()
39
    }
40
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component.rs
Line
Count
Source (jump to first uncovered line)
1
mod aliases;
2
mod builder;
3
mod canonicals;
4
mod components;
5
mod exports;
6
mod imports;
7
mod instances;
8
mod modules;
9
mod names;
10
mod start;
11
mod types;
12
13
pub use self::aliases::*;
14
pub use self::builder::*;
15
pub use self::canonicals::*;
16
pub use self::components::*;
17
pub use self::exports::*;
18
pub use self::imports::*;
19
pub use self::instances::*;
20
pub use self::modules::*;
21
pub use self::names::*;
22
pub use self::start::*;
23
pub use self::types::*;
24
25
use crate::{CustomSection, Encode, ProducersSection, RawCustomSection};
26
27
// Core sorts extended by the component model
28
const CORE_TYPE_SORT: u8 = 0x10;
29
const CORE_MODULE_SORT: u8 = 0x11;
30
const CORE_INSTANCE_SORT: u8 = 0x12;
31
32
const CORE_SORT: u8 = 0x00;
33
const FUNCTION_SORT: u8 = 0x01;
34
const VALUE_SORT: u8 = 0x02;
35
const TYPE_SORT: u8 = 0x03;
36
const COMPONENT_SORT: u8 = 0x04;
37
const INSTANCE_SORT: u8 = 0x05;
38
39
/// A WebAssembly component section.
40
///
41
/// Various builders defined in this crate already implement this trait, but you
42
/// can also implement it yourself for your own custom section builders, or use
43
/// `RawSection` to use a bunch of raw bytes as a section.
44
pub trait ComponentSection: Encode {
45
    /// Gets the section identifier for this section.
46
    fn id(&self) -> u8;
47
48
    /// Appends this section to the specified destination list of bytes.
49
0
    fn append_to_component(&self, dst: &mut Vec<u8>) {
50
0
        dst.push(self.id());
51
0
        self.encode(dst);
52
0
    }
Unexecuted instantiation: _RNvYNtNtCs5Pk8z11FdwQ_12wasm_encoder3raw10RawSectionNtNtB6_9component16ComponentSection19append_to_componentB6_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core6custom13CustomSectionNtNtB8_9component16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core6custom16RawCustomSectionNtNtB8_9component16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core9producers16ProducersSectionNtNtB8_9component16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicals24CanonicalFunctionSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component10components22NestedComponentSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component5names20ComponentNameSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component5types15CoreTypeSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component5types20ComponentTypeSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component7aliases21ComponentAliasSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component7exports22ComponentExportSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component7imports22ComponentImportSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component7modules13ModuleSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component9instances15InstanceSectionNtB6_16ComponentSection19append_to_componentB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder9component9instances24ComponentInstanceSectionNtB6_16ComponentSection19append_to_componentB8_
53
}
54
55
/// Known section identifiers of WebAssembly components.
56
///
57
/// These sections are supported by the component model proposal.
58
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
59
#[repr(u8)]
60
pub enum ComponentSectionId {
61
    /// The section is a core custom section.
62
    CoreCustom = 0,
63
    /// The section is a core module section.
64
    CoreModule = 1,
65
    /// The section is a core instance section.
66
    CoreInstance = 2,
67
    /// The section is a core type section.
68
    CoreType = 3,
69
    /// The section is a component section.
70
    Component = 4,
71
    /// The section is an instance section.
72
    Instance = 5,
73
    /// The section is an alias section.
74
    Alias = 6,
75
    /// The section is a type section.
76
    Type = 7,
77
    /// The section is a canonical function section.
78
    CanonicalFunction = 8,
79
    /// The section is a start section.
80
    Start = 9,
81
    /// The section is an import section.
82
    Import = 10,
83
    /// The section is an export section.
84
    Export = 11,
85
}
86
87
impl From<ComponentSectionId> for u8 {
88
    #[inline]
89
0
    fn from(id: ComponentSectionId) -> u8 {
90
0
        id as u8
91
0
    }
Unexecuted instantiation: _RNvXNtCs5Pk8z11FdwQ_12wasm_encoder9componenthINtNtCs1ujR1JRCAmI_4core7convert4FromNtB2_18ComponentSectionIdE4fromCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXNtCs5Pk8z11FdwQ_12wasm_encoder9componenthINtNtCs1ujR1JRCAmI_4core7convert4FromNtB2_18ComponentSectionIdE4fromB4_
92
}
93
94
impl Encode for ComponentSectionId {
95
0
    fn encode(&self, sink: &mut Vec<u8>) {
96
0
        sink.push(*self as u8);
97
0
    }
98
}
99
100
/// Represents a WebAssembly component that is being encoded.
101
///
102
/// Unlike core WebAssembly modules, the sections of a component
103
/// may appear in any order and may be repeated.
104
///
105
/// Components may also added as a section to other components.
106
#[derive(Clone, Debug)]
107
pub struct Component {
108
    bytes: Vec<u8>,
109
}
110
111
impl Component {
112
    /// The 8-byte header at the beginning of all components.
113
    #[rustfmt::skip]
114
    pub const HEADER: [u8; 8] = [
115
        // Magic
116
        0x00, 0x61, 0x73, 0x6D,
117
        // Version
118
        0x0d, 0x00, 0x01, 0x00,
119
    ];
120
121
    /// Begin writing a new `Component`.
122
0
    pub fn new() -> Self {
123
0
        Self {
124
0
            bytes: Self::HEADER.to_vec(),
125
0
        }
126
0
    }
127
128
    /// Finish writing this component and extract ownership of the encoded bytes.
129
0
    pub fn finish(self) -> Vec<u8> {
130
0
        self.bytes
131
0
    }
Unexecuted instantiation: _RNvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB5_9Component6finishCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB5_9Component6finishB7_
132
133
    /// Write a section to this component.
134
0
    pub fn section(&mut self, section: &impl ComponentSection) -> &mut Self {
135
0
        self.bytes.push(section.id());
136
0
        section.encode(&mut self.bytes);
137
0
        self
138
0
    }
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_10canonicals24CanonicalFunctionSectionECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_5types15CoreTypeSectionECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_5types20ComponentTypeSectionECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_7imports22ComponentImportSectionECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB8_3raw10RawSectionECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtNtB8_4core6custom13CustomSectionECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_10canonicals24CanonicalFunctionSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_10components22NestedComponentSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_5types15CoreTypeSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_5types20ComponentTypeSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_7aliases21ComponentAliasSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_7exports22ComponentExportSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_7imports22ComponentImportSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_7modules13ModuleSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_9instances15InstanceSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB6_9instances24ComponentInstanceSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtB8_3raw10RawSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtNtB8_4core6custom13CustomSectionEB8_
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtB6_9Component7sectionNtNtNtB8_4core6custom16RawCustomSectionEB8_
139
140
    /// View the encoded bytes.
141
0
    pub fn as_slice(&self) -> &[u8] {
142
0
        &self.bytes
143
0
    }
144
}
145
146
impl Default for Component {
147
0
    fn default() -> Self {
148
0
        Self::new()
149
0
    }
150
}
151
152
impl ComponentSection for CustomSection<'_> {
153
0
    fn id(&self) -> u8 {
154
0
        ComponentSectionId::CoreCustom.into()
155
0
    }
Unexecuted instantiation: _RNvXs2_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtNtNtB7_4core6custom13CustomSectionNtB5_16ComponentSection2idCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs2_NtCs5Pk8z11FdwQ_12wasm_encoder9componentNtNtNtB7_4core6custom13CustomSectionNtB5_16ComponentSection2idB7_
156
}
157
158
impl ComponentSection for RawCustomSection<'_> {
159
0
    fn id(&self) -> u8 {
160
0
        ComponentSectionId::CoreCustom.into()
161
0
    }
162
}
163
164
impl ComponentSection for ProducersSection {
165
0
    fn id(&self) -> u8 {
166
0
        ComponentSectionId::CoreCustom.into()
167
0
    }
168
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/aliases.rs
Line
Count
Source (jump to first uncovered line)
1
use super::{COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, CORE_TYPE_SORT, TYPE_SORT};
2
use crate::{
3
    encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
4
};
5
6
/// Represents the kinds of outer aliasable items in a component.
7
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8
pub enum ComponentOuterAliasKind {
9
    /// The alias is to a core module.
10
    CoreModule,
11
    /// The alias is to a core type.
12
    CoreType,
13
    /// The alias is to a type.
14
    Type,
15
    /// The alias is to a component.
16
    Component,
17
}
18
19
impl Encode for ComponentOuterAliasKind {
20
0
    fn encode(&self, sink: &mut Vec<u8>) {
21
0
        match self {
22
0
            Self::CoreModule => {
23
0
                sink.push(CORE_SORT);
24
0
                sink.push(CORE_MODULE_SORT);
25
0
            }
26
0
            Self::CoreType => {
27
0
                sink.push(CORE_SORT);
28
0
                sink.push(CORE_TYPE_SORT);
29
0
            }
30
0
            Self::Type => sink.push(TYPE_SORT),
31
0
            Self::Component => sink.push(COMPONENT_SORT),
32
        }
33
0
    }
34
}
35
36
/// An encoder for the alias section of WebAssembly component.
37
///
38
/// # Example
39
///
40
/// ```rust
41
/// use wasm_encoder::{Component, Alias, ComponentAliasSection, ComponentExportKind, ComponentOuterAliasKind};
42
///
43
/// let mut aliases = ComponentAliasSection::new();
44
/// aliases.alias(Alias::InstanceExport { instance: 0, kind: ComponentExportKind::Func, name: "f" });
45
/// aliases.alias(Alias::Outer { count: 0, kind: ComponentOuterAliasKind::Type, index: 1 });
46
///
47
/// let mut component = Component::new();
48
/// component.section(&aliases);
49
///
50
/// let bytes = component.finish();
51
/// ```
52
#[derive(Clone, Debug, Default)]
53
pub struct ComponentAliasSection {
54
    bytes: Vec<u8>,
55
    num_added: u32,
56
}
57
58
/// Different forms of aliases that can be inserted into a
59
/// [`ComponentAliasSection`].
60
#[derive(Copy, Clone, Debug)]
61
pub enum Alias<'a> {
62
    /// An alias of a component instance export.
63
    InstanceExport {
64
        /// The index of the component instance that's being aliased from.
65
        instance: u32,
66
        /// The kind of item that's being extracted from the component
67
        /// instance.
68
        kind: ComponentExportKind,
69
        /// The name of the export that's being aliased.
70
        name: &'a str,
71
    },
72
    /// Same as `InstanceExport`, but for core instances.
73
    #[allow(missing_docs)]
74
    CoreInstanceExport {
75
        instance: u32,
76
        kind: ExportKind,
77
        name: &'a str,
78
    },
79
    /// Aliasing an item from an outer component.
80
    Outer {
81
        /// The kind of item being aliased, either a type or a component.
82
        kind: ComponentOuterAliasKind,
83
        /// Number of levels "up" to go to lookup the index within. Level 0 is
84
        /// the current scope and level 1 is the enclosing scope, and so on.
85
        count: u32,
86
        /// The index of the item to alias within the scope referenced by
87
        /// `count`.
88
        index: u32,
89
    },
90
}
91
92
impl ComponentAliasSection {
93
    /// Create a new alias section encoder.
94
0
    pub fn new() -> Self {
95
0
        Self::default()
96
0
    }
97
98
    /// The number of aliases in the section.
99
0
    pub fn len(&self) -> u32 {
100
0
        self.num_added
101
0
    }
102
103
    /// Determines if the section is empty.
104
0
    pub fn is_empty(&self) -> bool {
105
0
        self.num_added == 0
106
0
    }
107
108
    /// Define an alias to a component instance's export.
109
0
    pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
110
0
        alias.encode(&mut self.bytes);
111
0
        self.num_added += 1;
112
0
        self
113
0
    }
114
}
115
116
impl Encode for ComponentAliasSection {
117
0
    fn encode(&self, sink: &mut Vec<u8>) {
118
0
        encode_section(sink, self.num_added, &self.bytes);
119
0
    }
120
}
121
122
impl ComponentSection for ComponentAliasSection {
123
0
    fn id(&self) -> u8 {
124
0
        ComponentSectionId::Alias.into()
125
0
    }
126
}
127
128
impl Encode for Alias<'_> {
129
0
    fn encode(&self, sink: &mut Vec<u8>) {
130
0
        match self {
131
            Alias::InstanceExport {
132
0
                instance,
133
0
                kind,
134
0
                name,
135
0
            } => {
136
0
                kind.encode(sink);
137
0
                sink.push(0x00);
138
0
                instance.encode(sink);
139
0
                name.encode(sink);
140
0
            }
141
            Alias::CoreInstanceExport {
142
0
                instance,
143
0
                kind,
144
0
                name,
145
0
            } => {
146
0
                sink.push(CORE_SORT);
147
0
                kind.encode(sink);
148
0
                sink.push(0x01);
149
0
                instance.encode(sink);
150
0
                name.encode(sink);
151
0
            }
152
0
            Alias::Outer { kind, count, index } => {
153
0
                kind.encode(sink);
154
0
                sink.push(0x02);
155
0
                count.encode(sink);
156
0
                index.encode(sink);
157
0
            }
158
        }
159
0
    }
160
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/builder.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::component::*;
2
use crate::{ExportKind, Module, RawSection, ValType};
3
use std::mem;
4
5
/// Convenience type to build a component incrementally and automatically keep
6
/// track of index spaces.
7
///
8
/// This type is intended to be a wrapper around the [`Component`] encoding type
9
/// which is useful for building it up incrementally over time. This type will
10
/// automatically collect definitions into sections and reports the index of all
11
/// items added by keeping track of indices internally.
12
#[derive(Debug, Default)]
13
pub struct ComponentBuilder {
14
    /// The binary component that's being built.
15
    component: Component,
16
17
    /// The last section which was appended to during encoding. This type is
18
    /// generated by the `section_accessors` macro below.
19
    ///
20
    /// When something is encoded this is used if it matches the kind of item
21
    /// being encoded, otherwise it's "flushed" to the output component and a
22
    /// new section is started.
23
    last_section: LastSection,
24
25
    // Core index spaces
26
    core_modules: u32,
27
    core_funcs: u32,
28
    core_types: u32,
29
    core_memories: u32,
30
    core_tables: u32,
31
    core_instances: u32,
32
    core_tags: u32,
33
    core_globals: u32,
34
35
    // Component index spaces
36
    funcs: u32,
37
    instances: u32,
38
    types: u32,
39
    components: u32,
40
    values: u32,
41
}
42
43
impl ComponentBuilder {
44
    /// Returns the current number of core modules.
45
0
    pub fn core_module_count(&self) -> u32 {
46
0
        self.core_modules
47
0
    }
48
49
    /// Returns the current number of core funcs.
50
0
    pub fn core_func_count(&self) -> u32 {
51
0
        self.core_funcs
52
0
    }
53
54
    /// Returns the current number of core types.
55
0
    pub fn core_type_count(&self) -> u32 {
56
0
        self.core_types
57
0
    }
58
59
    /// Returns the current number of core memories.
60
0
    pub fn core_memory_count(&self) -> u32 {
61
0
        self.core_memories
62
0
    }
63
64
    /// Returns the current number of core tables.
65
0
    pub fn core_table_count(&self) -> u32 {
66
0
        self.core_tables
67
0
    }
68
69
    /// Returns the current number of core instances.
70
0
    pub fn core_instance_count(&self) -> u32 {
71
0
        self.core_instances
72
0
    }
73
74
    /// Returns the current number of core tags.
75
0
    pub fn core_tag_count(&self) -> u32 {
76
0
        self.core_tags
77
0
    }
78
79
    /// Returns the current number of core globals.
80
0
    pub fn core_global_count(&self) -> u32 {
81
0
        self.core_globals
82
0
    }
83
84
    /// Returns the current number of component funcs.
85
0
    pub fn func_count(&self) -> u32 {
86
0
        self.funcs
87
0
    }
88
89
    /// Returns the current number of component instances.
90
0
    pub fn instance_count(&self) -> u32 {
91
0
        self.instances
92
0
    }
93
94
    /// Returns the current number of component values.
95
0
    pub fn value_count(&self) -> u32 {
96
0
        self.values
97
0
    }
98
99
    /// Returns the current number of components.
100
0
    pub fn component_count(&self) -> u32 {
101
0
        self.components
102
0
    }
103
104
    /// Returns the current number of component types.
105
0
    pub fn type_count(&self) -> u32 {
106
0
        self.types
107
0
    }
108
109
    /// Completes this component and returns the binary encoding of the entire
110
    /// component.
111
0
    pub fn finish(mut self) -> Vec<u8> {
112
0
        self.flush();
113
0
        self.component.finish()
114
0
    }
115
116
    /// Encodes a core wasm `Module` into this component, returning its index.
117
0
    pub fn core_module(&mut self, module: &Module) -> u32 {
118
0
        self.flush();
119
0
        self.component.section(&ModuleSection(module));
120
0
        inc(&mut self.core_modules)
121
0
    }
122
123
    /// Encodes a core wasm `module` into this component, returning its index.
124
0
    pub fn core_module_raw(&mut self, module: &[u8]) -> u32 {
125
0
        self.flush();
126
0
        self.component.section(&RawSection {
127
0
            id: ComponentSectionId::CoreModule.into(),
128
0
            data: module,
129
0
        });
130
0
        inc(&mut self.core_modules)
131
0
    }
132
133
    /// Instantiates a core wasm module at `module_index` with the `args`
134
    /// provided.
135
    ///
136
    /// Returns the index of the core wasm instance crated.
137
0
    pub fn core_instantiate<'a, A>(&mut self, module_index: u32, args: A) -> u32
138
0
    where
139
0
        A: IntoIterator<Item = (&'a str, ModuleArg)>,
140
0
        A::IntoIter: ExactSizeIterator,
141
0
    {
142
0
        self.instances().instantiate(module_index, args);
143
0
        inc(&mut self.core_instances)
144
0
    }
145
146
    /// Creates a new core wasm instance from the `exports` provided.
147
    ///
148
    /// Returns the index of the core wasm instance crated.
149
0
    pub fn core_instantiate_exports<'a, E>(&mut self, exports: E) -> u32
150
0
    where
151
0
        E: IntoIterator<Item = (&'a str, ExportKind, u32)>,
152
0
        E::IntoIter: ExactSizeIterator,
153
0
    {
154
0
        self.instances().export_items(exports);
155
0
        inc(&mut self.core_instances)
156
0
    }
157
158
    /// Creates a new aliased item where the core `instance` specified has its
159
    /// export `name` aliased out with the `kind` specified.
160
    ///
161
    /// Returns the index of the item crated.
162
0
    pub fn core_alias_export(&mut self, instance: u32, name: &str, kind: ExportKind) -> u32 {
163
0
        self.alias(Alias::CoreInstanceExport {
164
0
            instance,
165
0
            kind,
166
0
            name,
167
0
        })
168
0
    }
169
170
    /// Adds a new alias to this component
171
0
    pub fn alias(&mut self, alias: Alias<'_>) -> u32 {
172
0
        self.aliases().alias(alias);
173
0
        match alias {
174
0
            Alias::InstanceExport { kind, .. } => self.inc_kind(kind),
175
0
            Alias::CoreInstanceExport { kind, .. } => self.inc_core_kind(kind),
176
            Alias::Outer {
177
                kind: ComponentOuterAliasKind::Type,
178
                ..
179
0
            } => inc(&mut self.types),
180
            Alias::Outer {
181
                kind: ComponentOuterAliasKind::CoreModule,
182
                ..
183
0
            } => inc(&mut self.core_modules),
184
            Alias::Outer {
185
                kind: ComponentOuterAliasKind::Component,
186
                ..
187
0
            } => inc(&mut self.components),
188
            Alias::Outer {
189
                kind: ComponentOuterAliasKind::CoreType,
190
                ..
191
0
            } => inc(&mut self.core_types),
192
        }
193
0
    }
194
195
    /// Creates an alias to a previous component instance's exported item.
196
    ///
197
    /// The `instance` provided is the instance to access and the `name` is the
198
    /// item to access.
199
    ///
200
    /// Returns the index of the new item defined.
201
0
    pub fn alias_export(&mut self, instance: u32, name: &str, kind: ComponentExportKind) -> u32 {
202
0
        self.alias(Alias::InstanceExport {
203
0
            instance,
204
0
            kind,
205
0
            name,
206
0
        })
207
0
    }
208
209
0
    fn inc_kind(&mut self, kind: ComponentExportKind) -> u32 {
210
0
        match kind {
211
0
            ComponentExportKind::Func => inc(&mut self.funcs),
212
0
            ComponentExportKind::Module => inc(&mut self.core_modules),
213
0
            ComponentExportKind::Type => inc(&mut self.types),
214
0
            ComponentExportKind::Component => inc(&mut self.components),
215
0
            ComponentExportKind::Instance => inc(&mut self.instances),
216
0
            ComponentExportKind::Value => inc(&mut self.values),
217
        }
218
0
    }
219
220
0
    fn inc_core_kind(&mut self, kind: ExportKind) -> u32 {
221
0
        match kind {
222
0
            ExportKind::Func => inc(&mut self.core_funcs),
223
0
            ExportKind::Table => inc(&mut self.core_tables),
224
0
            ExportKind::Memory => inc(&mut self.core_memories),
225
0
            ExportKind::Global => inc(&mut self.core_globals),
226
0
            ExportKind::Tag => inc(&mut self.core_tags),
227
        }
228
0
    }
229
230
    /// Lowers the `func_index` component function into a core wasm function
231
    /// using the `options` provided.
232
    ///
233
    /// Returns the index of the core wasm function created.
234
0
    pub fn lower_func<O>(&mut self, func_index: u32, options: O) -> u32
235
0
    where
236
0
        O: IntoIterator<Item = CanonicalOption>,
237
0
        O::IntoIter: ExactSizeIterator,
238
0
    {
239
0
        self.canonical_functions().lower(func_index, options);
240
0
        inc(&mut self.core_funcs)
241
0
    }
242
243
    /// Lifts the core wasm `core_func_index` function with the component
244
    /// function type `type_index` and `options`.
245
    ///
246
    /// Returns the index of the component function created.
247
0
    pub fn lift_func<O>(&mut self, core_func_index: u32, type_index: u32, options: O) -> u32
248
0
    where
249
0
        O: IntoIterator<Item = CanonicalOption>,
250
0
        O::IntoIter: ExactSizeIterator,
251
0
    {
252
0
        self.canonical_functions()
253
0
            .lift(core_func_index, type_index, options);
254
0
        inc(&mut self.funcs)
255
0
    }
256
257
    /// Imports a new item into this component with the `name` and `ty` specified.
258
0
    pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> u32 {
259
0
        let ret = match &ty {
260
0
            ComponentTypeRef::Instance(_) => inc(&mut self.instances),
261
0
            ComponentTypeRef::Func(_) => inc(&mut self.funcs),
262
0
            ComponentTypeRef::Type(..) => inc(&mut self.types),
263
0
            ComponentTypeRef::Component(_) => inc(&mut self.components),
264
0
            ComponentTypeRef::Module(_) => inc(&mut self.core_modules),
265
0
            ComponentTypeRef::Value(_) => inc(&mut self.values),
266
        };
267
0
        self.imports().import(name, ty);
268
0
        ret
269
0
    }
270
271
    /// Exports a new item from this component with the `name` and `kind`
272
    /// specified.
273
    ///
274
    /// The `idx` is the item to export and the `ty` is an optional type to
275
    /// ascribe to the export.
276
0
    pub fn export(
277
0
        &mut self,
278
0
        name: &str,
279
0
        kind: ComponentExportKind,
280
0
        idx: u32,
281
0
        ty: Option<ComponentTypeRef>,
282
0
    ) -> u32 {
283
0
        self.exports().export(name, kind, idx, ty);
284
0
        self.inc_kind(kind)
285
0
    }
286
287
    /// Creates a new encoder for the next core type in this component.
288
0
    pub fn core_type(&mut self) -> (u32, CoreTypeEncoder<'_>) {
289
0
        (inc(&mut self.core_types), self.core_types().ty())
290
0
    }
291
292
    /// Creates a new encoder for the next type in this component.
293
0
    pub fn ty(&mut self) -> (u32, ComponentTypeEncoder<'_>) {
294
0
        (inc(&mut self.types), self.types().ty())
295
0
    }
296
297
    /// Creates a new instance type within this component.
298
0
    pub fn type_instance(&mut self, ty: &InstanceType) -> u32 {
299
0
        self.types().instance(ty);
300
0
        inc(&mut self.types)
301
0
    }
302
303
    /// Creates a new component type within this component.
304
0
    pub fn type_component(&mut self, ty: &ComponentType) -> u32 {
305
0
        self.types().component(ty);
306
0
        inc(&mut self.types)
307
0
    }
308
309
    /// Creates a new defined component type within this component.
310
0
    pub fn type_defined(&mut self) -> (u32, ComponentDefinedTypeEncoder<'_>) {
311
0
        (inc(&mut self.types), self.types().defined_type())
312
0
    }
313
314
    /// Creates a new component function type within this component.
315
0
    pub fn type_function(&mut self) -> (u32, ComponentFuncTypeEncoder<'_>) {
316
0
        (inc(&mut self.types), self.types().function())
317
0
    }
318
319
    /// Declares a
320
0
    pub fn type_resource(&mut self, rep: ValType, dtor: Option<u32>) -> u32 {
321
0
        self.types().resource(rep, dtor);
322
0
        inc(&mut self.types)
323
0
    }
324
325
    /// Defines a new subcomponent of this component.
326
0
    pub fn component(&mut self, mut builder: ComponentBuilder) -> u32 {
327
0
        builder.flush();
328
0
        self.flush();
329
0
        self.component
330
0
            .section(&NestedComponentSection(&builder.component));
331
0
        inc(&mut self.components)
332
0
    }
333
334
    /// Defines a new subcomponent of this component.
335
0
    pub fn component_raw(&mut self, data: &[u8]) -> u32 {
336
0
        let raw_section = RawSection {
337
0
            id: ComponentSectionId::Component.into(),
338
0
            data,
339
0
        };
340
0
        self.flush();
341
0
        self.component.section(&raw_section);
342
0
        inc(&mut self.components)
343
0
    }
344
345
    /// Instantiates the `component_index` specified with the `args` specified.
346
0
    pub fn instantiate<A, S>(&mut self, component_index: u32, args: A) -> u32
347
0
    where
348
0
        A: IntoIterator<Item = (S, ComponentExportKind, u32)>,
349
0
        A::IntoIter: ExactSizeIterator,
350
0
        S: AsRef<str>,
351
0
    {
352
0
        self.component_instances()
353
0
            .instantiate(component_index, args);
354
0
        inc(&mut self.instances)
355
0
    }
356
357
    /// Declares a new `resource.drop` intrinsic.
358
0
    pub fn resource_drop(&mut self, ty: u32) -> u32 {
359
0
        self.canonical_functions().resource_drop(ty);
360
0
        inc(&mut self.core_funcs)
361
0
    }
362
363
    /// Declares a new `resource.new` intrinsic.
364
0
    pub fn resource_new(&mut self, ty: u32) -> u32 {
365
0
        self.canonical_functions().resource_new(ty);
366
0
        inc(&mut self.core_funcs)
367
0
    }
368
369
    /// Declares a new `resource.rep` intrinsic.
370
0
    pub fn resource_rep(&mut self, ty: u32) -> u32 {
371
0
        self.canonical_functions().resource_rep(ty);
372
0
        inc(&mut self.core_funcs)
373
0
    }
374
375
    /// Adds a new custom section to this component.
376
0
    pub fn custom_section(&mut self, section: &CustomSection<'_>) {
377
0
        self.flush();
378
0
        self.component.section(section);
379
0
    }
380
381
    /// Adds a new custom section to this component.
382
0
    pub fn raw_custom_section(&mut self, section: &[u8]) {
383
0
        self.flush();
384
0
        self.component.section(&RawCustomSection(section));
385
0
    }
386
}
387
388
// Helper macro to generate methods on `ComponentBuilder` to get specific
389
// section encoders that automatically flush and write out prior sections as
390
// necessary.
391
macro_rules! section_accessors {
392
    ($($method:ident => $section:ident)*) => (
393
        #[derive(Debug, Default)]
394
        enum LastSection {
395
            #[default]
396
            None,
397
            $($section($section),)*
398
        }
399
400
        impl ComponentBuilder {
401
            $(
402
0
                fn $method(&mut self) -> &mut $section {
403
0
                    match &self.last_section {
404
                        // The last encoded section matches the section that's
405
                        // being requested, so no change is necessary.
406
0
                        LastSection::$section(_) => {}
407
408
                        // Otherwise the last section didn't match this section,
409
                        // so flush any prior section if needed and start
410
                        // encoding the desired section of this method.
411
0
                        _ => {
412
0
                            self.flush();
413
0
                            self.last_section = LastSection::$section($section::new());
414
0
                        }
415
                    }
416
0
                    match &mut self.last_section {
417
0
                        LastSection::$section(ret) => ret,
418
0
                        _ => unreachable!()
419
                    }
420
0
                }
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7builderNtB5_16ComponentBuilder19component_instances
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7builderNtB5_16ComponentBuilder9instances
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7builderNtB5_16ComponentBuilder19canonical_functions
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7builderNtB5_16ComponentBuilder7aliases
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7builderNtB5_16ComponentBuilder7exports
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7builderNtB5_16ComponentBuilder7imports
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7builderNtB5_16ComponentBuilder5types
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7builderNtB5_16ComponentBuilder10core_types
421
            )*
422
423
            /// Writes out the last section into the final component binary if
424
            /// there is a section specified, otherwise does nothing.
425
0
            fn flush(&mut self) {
426
0
                match mem::take(&mut self.last_section) {
427
0
                    LastSection::None => {}
428
                    $(
429
0
                        LastSection::$section(section) => {
430
0
                            self.component.section(&section);
431
0
                        }
432
                    )*
433
                }
434
0
            }
435
436
        }
437
    )
438
}
439
440
section_accessors! {
441
    component_instances => ComponentInstanceSection
442
    instances => InstanceSection
443
    canonical_functions => CanonicalFunctionSection
444
    aliases => ComponentAliasSection
445
    exports => ComponentExportSection
446
    imports => ComponentImportSection
447
    types => ComponentTypeSection
448
    core_types => CoreTypeSection
449
}
450
451
0
fn inc(idx: &mut u32) -> u32 {
452
0
    let ret = *idx;
453
0
    *idx += 1;
454
0
    ret
455
0
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/canonicals.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, ComponentSection, ComponentSectionId, Encode};
2
3
/// Represents options for canonical function definitions.
4
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5
pub enum CanonicalOption {
6
    /// The string types in the function signature are UTF-8 encoded.
7
    UTF8,
8
    /// The string types in the function signature are UTF-16 encoded.
9
    UTF16,
10
    /// The string types in the function signature are compact UTF-16 encoded.
11
    CompactUTF16,
12
    /// The memory to use if the lifting or lowering of a function requires memory access.
13
    ///
14
    /// The value is an index to a core memory.
15
    Memory(u32),
16
    /// The realloc function to use if the lifting or lowering of a function requires memory
17
    /// allocation.
18
    ///
19
    /// The value is an index to a core function of type `(func (param i32 i32 i32 i32) (result i32))`.
20
    Realloc(u32),
21
    /// The post-return function to use if the lifting of a function requires
22
    /// cleanup after the function returns.
23
    PostReturn(u32),
24
}
25
26
impl Encode for CanonicalOption {
27
0
    fn encode(&self, sink: &mut Vec<u8>) {
28
0
        match self {
29
0
            Self::UTF8 => sink.push(0x00),
30
0
            Self::UTF16 => sink.push(0x01),
31
0
            Self::CompactUTF16 => sink.push(0x02),
32
0
            Self::Memory(idx) => {
33
0
                sink.push(0x03);
34
0
                idx.encode(sink);
35
0
            }
36
0
            Self::Realloc(idx) => {
37
0
                sink.push(0x04);
38
0
                idx.encode(sink);
39
0
            }
40
0
            Self::PostReturn(idx) => {
41
0
                sink.push(0x05);
42
0
                idx.encode(sink);
43
0
            }
44
        }
45
0
    }
46
}
47
48
/// An encoder for the canonical function section of WebAssembly components.
49
///
50
/// # Example
51
///
52
/// ```
53
/// use wasm_encoder::{Component, CanonicalFunctionSection, CanonicalOption};
54
///
55
/// let mut functions = CanonicalFunctionSection::new();
56
/// functions.lift(0, 0, [CanonicalOption::UTF8]);
57
///
58
/// let mut component = Component::new();
59
/// component.section(&functions);
60
///
61
/// let bytes = component.finish();
62
/// ```
63
#[derive(Clone, Debug, Default)]
64
pub struct CanonicalFunctionSection {
65
    bytes: Vec<u8>,
66
    num_added: u32,
67
}
68
69
impl CanonicalFunctionSection {
70
    /// Construct a new component function section encoder.
71
0
    pub fn new() -> Self {
72
0
        Self::default()
73
0
    }
Unexecuted instantiation: _RNvMs_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicalsNtB4_24CanonicalFunctionSection3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicalsNtB4_24CanonicalFunctionSection3newB8_
74
75
    /// The number of functions in the section.
76
0
    pub fn len(&self) -> u32 {
77
0
        self.num_added
78
0
    }
79
80
    /// Determines if the section is empty.
81
0
    pub fn is_empty(&self) -> bool {
82
0
        self.num_added == 0
83
0
    }
84
85
    /// Define a function that will lift a core WebAssembly function to the canonical ABI.
86
0
    pub fn lift<O>(&mut self, core_func_index: u32, type_index: u32, options: O) -> &mut Self
87
0
    where
88
0
        O: IntoIterator<Item = CanonicalOption>,
89
0
        O::IntoIter: ExactSizeIterator,
90
0
    {
91
0
        let options = options.into_iter();
92
0
        self.bytes.push(0x00);
93
0
        self.bytes.push(0x00);
94
0
        core_func_index.encode(&mut self.bytes);
95
0
        options.len().encode(&mut self.bytes);
96
0
        for option in options {
97
0
            option.encode(&mut self.bytes);
98
0
        }
99
0
        type_index.encode(&mut self.bytes);
100
0
        self.num_added += 1;
101
0
        self
102
0
    }
Unexecuted instantiation: _RINvMs_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicalsNtB5_24CanonicalFunctionSection4liftINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtB5_15CanonicalOptionEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicalsNtB5_24CanonicalFunctionSection4liftpEB9_
103
104
    /// Define a function that will lower a canonical ABI function to a core WebAssembly function.
105
0
    pub fn lower<O>(&mut self, func_index: u32, options: O) -> &mut Self
106
0
    where
107
0
        O: IntoIterator<Item = CanonicalOption>,
108
0
        O::IntoIter: ExactSizeIterator,
109
0
    {
110
0
        let options = options.into_iter();
111
0
        self.bytes.push(0x01);
112
0
        self.bytes.push(0x00);
113
0
        func_index.encode(&mut self.bytes);
114
0
        options.len().encode(&mut self.bytes);
115
0
        for option in options {
116
0
            option.encode(&mut self.bytes);
117
0
        }
118
0
        self.num_added += 1;
119
0
        self
120
0
    }
Unexecuted instantiation: _RINvMs_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicalsNtB5_24CanonicalFunctionSection5lowerINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtB5_15CanonicalOptionEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicalsNtB5_24CanonicalFunctionSection5lowerpEB9_
121
122
    /// Defines a function which will create an owned handle to the resource
123
    /// specified by `ty_index`.
124
0
    pub fn resource_new(&mut self, ty_index: u32) -> &mut Self {
125
0
        self.bytes.push(0x02);
126
0
        ty_index.encode(&mut self.bytes);
127
0
        self.num_added += 1;
128
0
        self
129
0
    }
130
131
    /// Defines a function which will drop the specified type of handle.
132
0
    pub fn resource_drop(&mut self, ty_index: u32) -> &mut Self {
133
0
        self.bytes.push(0x03);
134
0
        ty_index.encode(&mut self.bytes);
135
0
        self.num_added += 1;
136
0
        self
137
0
    }
138
139
    /// Defines a function which will return the representation of the specified
140
    /// resource type.
141
0
    pub fn resource_rep(&mut self, ty_index: u32) -> &mut Self {
142
0
        self.bytes.push(0x04);
143
0
        ty_index.encode(&mut self.bytes);
144
0
        self.num_added += 1;
145
0
        self
146
0
    }
147
}
148
149
impl Encode for CanonicalFunctionSection {
150
0
    fn encode(&self, sink: &mut Vec<u8>) {
151
0
        encode_section(sink, self.num_added, &self.bytes);
152
0
    }
153
}
154
155
impl ComponentSection for CanonicalFunctionSection {
156
0
    fn id(&self) -> u8 {
157
0
        ComponentSectionId::CanonicalFunction.into()
158
0
    }
Unexecuted instantiation: _RNvXs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicalsNtB5_24CanonicalFunctionSectionNtB7_16ComponentSection2idCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component10canonicalsNtB5_24CanonicalFunctionSectionNtB7_16ComponentSection2idB9_
159
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/components.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{Component, ComponentSection, ComponentSectionId, Encode};
2
3
/// An encoder for the component section of WebAssembly components.
4
///
5
/// # Example
6
///
7
/// ```rust
8
/// use wasm_encoder::{Component, NestedComponentSection};
9
///
10
/// let mut nested = Component::new();
11
/// let mut component = Component::new();
12
/// component.section(&NestedComponentSection(&nested));
13
///
14
/// let bytes = component.finish();
15
/// ```
16
#[derive(Clone, Debug)]
17
pub struct NestedComponentSection<'a>(pub &'a Component);
18
19
impl Encode for NestedComponentSection<'_> {
20
0
    fn encode(&self, sink: &mut Vec<u8>) {
21
0
        self.0.bytes.encode(sink);
22
0
    }
23
}
24
25
impl ComponentSection for NestedComponentSection<'_> {
26
0
    fn id(&self) -> u8 {
27
0
        ComponentSectionId::Component.into()
28
0
    }
29
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/exports.rs
Line
Count
Source (jump to first uncovered line)
1
use super::{
2
    COMPONENT_SORT, CORE_MODULE_SORT, CORE_SORT, FUNCTION_SORT, INSTANCE_SORT, TYPE_SORT,
3
    VALUE_SORT,
4
};
5
use crate::{encode_section, ComponentSection, ComponentSectionId, ComponentTypeRef, Encode};
6
7
/// Represents the kind of an export from a WebAssembly component.
8
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9
pub enum ComponentExportKind {
10
    /// The export is a core module.
11
    Module,
12
    /// The export is a function.
13
    Func,
14
    /// The export is a value.
15
    Value,
16
    /// The export is a type.
17
    Type,
18
    /// The export is an instance.
19
    Instance,
20
    /// The export is a component.
21
    Component,
22
}
23
24
impl Encode for ComponentExportKind {
25
0
    fn encode(&self, sink: &mut Vec<u8>) {
26
0
        match self {
27
0
            Self::Module => {
28
0
                sink.push(CORE_SORT);
29
0
                sink.push(CORE_MODULE_SORT);
30
0
            }
31
0
            Self::Func => {
32
0
                sink.push(FUNCTION_SORT);
33
0
            }
34
0
            Self::Value => {
35
0
                sink.push(VALUE_SORT);
36
0
            }
37
0
            Self::Type => {
38
0
                sink.push(TYPE_SORT);
39
0
            }
40
0
            Self::Instance => {
41
0
                sink.push(INSTANCE_SORT);
42
0
            }
43
0
            Self::Component => {
44
0
                sink.push(COMPONENT_SORT);
45
0
            }
46
        }
47
0
    }
48
}
49
50
/// An encoder for the export section of WebAssembly component.
51
///
52
/// # Example
53
///
54
/// ```rust
55
/// use wasm_encoder::{Component, ComponentExportSection, ComponentExportKind};
56
///
57
/// // This exports a function named "foo"
58
/// let mut exports = ComponentExportSection::new();
59
/// exports.export("foo", ComponentExportKind::Func, 0, None);
60
///
61
/// let mut component = Component::new();
62
/// component.section(&exports);
63
///
64
/// let bytes = component.finish();
65
/// ```
66
#[derive(Clone, Debug, Default)]
67
pub struct ComponentExportSection {
68
    bytes: Vec<u8>,
69
    num_added: u32,
70
}
71
72
impl ComponentExportSection {
73
    /// Create a new component export section encoder.
74
0
    pub fn new() -> Self {
75
0
        Self::default()
76
0
    }
77
78
    /// The number of exports in the section.
79
0
    pub fn len(&self) -> u32 {
80
0
        self.num_added
81
0
    }
82
83
    /// Determines if the section is empty.
84
0
    pub fn is_empty(&self) -> bool {
85
0
        self.num_added == 0
86
0
    }
87
88
    /// Define an export in the export section.
89
0
    pub fn export(
90
0
        &mut self,
91
0
        name: &str,
92
0
        kind: ComponentExportKind,
93
0
        index: u32,
94
0
        ty: Option<ComponentTypeRef>,
95
0
    ) -> &mut Self {
96
0
        crate::component::imports::push_extern_name_byte(&mut self.bytes, name);
97
0
        name.encode(&mut self.bytes);
98
0
        kind.encode(&mut self.bytes);
99
0
        index.encode(&mut self.bytes);
100
0
        match ty {
101
0
            Some(ty) => {
102
0
                self.bytes.push(0x01);
103
0
                ty.encode(&mut self.bytes);
104
0
            }
105
0
            None => {
106
0
                self.bytes.push(0x00);
107
0
            }
108
        }
109
0
        self.num_added += 1;
110
0
        self
111
0
    }
112
}
113
114
impl Encode for ComponentExportSection {
115
0
    fn encode(&self, sink: &mut Vec<u8>) {
116
0
        encode_section(sink, self.num_added, &self.bytes);
117
0
    }
118
}
119
120
impl ComponentSection for ComponentExportSection {
121
0
    fn id(&self) -> u8 {
122
0
        ComponentSectionId::Export.into()
123
0
    }
124
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/imports.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{
2
    encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, ComponentValType,
3
    Encode,
4
};
5
6
/// Represents the possible type bounds for type references.
7
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
8
pub enum TypeBounds {
9
    /// The type is bounded by equality to the type index specified.
10
    Eq(u32),
11
    /// This type is a fresh resource type,
12
    SubResource,
13
}
14
15
impl Encode for TypeBounds {
16
0
    fn encode(&self, sink: &mut Vec<u8>) {
17
0
        match self {
18
0
            Self::Eq(i) => {
19
0
                sink.push(0x00);
20
0
                i.encode(sink);
21
0
            }
22
0
            Self::SubResource => sink.push(0x01),
23
        }
24
0
    }
25
}
26
27
/// Represents a reference to a type.
28
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
29
pub enum ComponentTypeRef {
30
    /// The reference is to a core module type.
31
    ///
32
    /// The index is expected to be core type index to a core module type.
33
    Module(u32),
34
    /// The reference is to a function type.
35
    ///
36
    /// The index is expected to be a type index to a function type.
37
    Func(u32),
38
    /// The reference is to a value type.
39
    Value(ComponentValType),
40
    /// The reference is to a bounded type.
41
    Type(TypeBounds),
42
    /// The reference is to an instance type.
43
    ///
44
    /// The index is expected to be a type index to an instance type.
45
    Instance(u32),
46
    /// The reference is to a component type.
47
    ///
48
    /// The index is expected to be a type index to a component type.
49
    Component(u32),
50
}
51
52
impl ComponentTypeRef {
53
    /// Gets the export kind of the reference.
54
0
    pub fn kind(&self) -> ComponentExportKind {
55
0
        match self {
56
0
            Self::Module(_) => ComponentExportKind::Module,
57
0
            Self::Func(_) => ComponentExportKind::Func,
58
0
            Self::Value(_) => ComponentExportKind::Value,
59
0
            Self::Type(..) => ComponentExportKind::Type,
60
0
            Self::Instance(_) => ComponentExportKind::Instance,
61
0
            Self::Component(_) => ComponentExportKind::Component,
62
        }
63
0
    }
64
}
65
66
impl Encode for ComponentTypeRef {
67
0
    fn encode(&self, sink: &mut Vec<u8>) {
68
0
        self.kind().encode(sink);
69
0
70
0
        match self {
71
0
            Self::Module(idx) | Self::Func(idx) | Self::Instance(idx) | Self::Component(idx) => {
72
0
                idx.encode(sink);
73
0
            }
74
0
            Self::Value(ty) => ty.encode(sink),
75
0
            Self::Type(bounds) => bounds.encode(sink),
76
        }
77
0
    }
78
}
79
80
/// An encoder for the import section of WebAssembly components.
81
///
82
/// # Example
83
///
84
/// ```rust
85
/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType, ComponentImportSection, ComponentTypeRef};
86
///
87
/// let mut types = ComponentTypeSection::new();
88
///
89
/// // Define a function type of `[string, string] -> string`.
90
/// types
91
///   .function()
92
///   .params(
93
///     [
94
///       ("a", PrimitiveValType::String),
95
///       ("b", PrimitiveValType::String)
96
///     ]
97
///   )
98
///   .result(PrimitiveValType::String);
99
///
100
/// // This imports a function named `f` with the type defined above
101
/// let mut imports = ComponentImportSection::new();
102
/// imports.import("f", ComponentTypeRef::Func(0));
103
///
104
/// let mut component = Component::new();
105
/// component.section(&types);
106
/// component.section(&imports);
107
///
108
/// let bytes = component.finish();
109
/// ```
110
#[derive(Clone, Debug, Default)]
111
pub struct ComponentImportSection {
112
    bytes: Vec<u8>,
113
    num_added: u32,
114
}
115
116
impl ComponentImportSection {
117
    /// Create a new component import section encoder.
118
0
    pub fn new() -> Self {
119
0
        Self::default()
120
0
    }
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7importsNtB5_22ComponentImportSection3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7importsNtB5_22ComponentImportSection3newB9_
121
122
    /// The number of imports in the section.
123
0
    pub fn len(&self) -> u32 {
124
0
        self.num_added
125
0
    }
126
127
    /// Determines if the section is empty.
128
0
    pub fn is_empty(&self) -> bool {
129
0
        self.num_added == 0
130
0
    }
131
132
    /// Define an import in the component import section.
133
0
    pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
134
0
        push_extern_name_byte(&mut self.bytes, name);
135
0
        name.encode(&mut self.bytes);
136
0
        ty.encode(&mut self.bytes);
137
0
        self.num_added += 1;
138
0
        self
139
0
    }
140
}
141
142
impl Encode for ComponentImportSection {
143
0
    fn encode(&self, sink: &mut Vec<u8>) {
144
0
        encode_section(sink, self.num_added, &self.bytes);
145
0
    }
146
}
147
148
impl ComponentSection for ComponentImportSection {
149
0
    fn id(&self) -> u8 {
150
0
        ComponentSectionId::Import.into()
151
0
    }
Unexecuted instantiation: _RNvXs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7importsNtB5_22ComponentImportSectionNtB7_16ComponentSection2idCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component7importsNtB5_22ComponentImportSectionNtB7_16ComponentSection2idB9_
152
}
153
154
/// Prior to WebAssembly/component-model#263 import and export names were
155
/// discriminated with a leading byte indicating what kind of import they are.
156
/// After that PR though names are always prefixed with a 0x00 byte.
157
///
158
/// This function is a compatibility shim for the time being while this change
159
/// is being rolled out. That PR is technically a spec-breaking change relative
160
/// to prior but we want old tooling to continue to work with new modules. To
161
/// handle that names that look like IDs, `a:b/c`, get an 0x01 prefix instead of
162
/// the spec-defined 0x00 prefix. That makes components produced by current
163
/// versions of this crate compatible with older parsers.
164
///
165
/// Note that wasmparser has a similar case where it parses either 0x01 or 0x00.
166
/// That means that the selection of a byte here doesn't actually matter for
167
/// wasmparser's own validation. Eventually this will go away and an 0x00 byte
168
/// will always be emitted to align with the spec.
169
0
pub(crate) fn push_extern_name_byte(bytes: &mut Vec<u8>, name: &str) {
170
0
    if name.contains(':') {
171
0
        bytes.push(0x01);
172
0
    } else {
173
0
        bytes.push(0x00);
174
0
    }
175
0
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/instances.rs
Line
Count
Source (jump to first uncovered line)
1
use super::CORE_INSTANCE_SORT;
2
use crate::{
3
    encode_section, ComponentExportKind, ComponentSection, ComponentSectionId, Encode, ExportKind,
4
};
5
6
/// Represents an argument to a module instantiation.
7
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8
pub enum ModuleArg {
9
    /// The argument is an instance.
10
    Instance(u32),
11
}
12
13
impl Encode for ModuleArg {
14
0
    fn encode(&self, sink: &mut Vec<u8>) {
15
0
        let (sort, idx) = match self {
16
0
            Self::Instance(idx) => (CORE_INSTANCE_SORT, *idx),
17
0
        };
18
0
        sink.push(sort);
19
0
        idx.encode(sink);
20
0
    }
21
}
22
23
/// An encoder for the core instance section of WebAssembly components.
24
///
25
/// # Example
26
///
27
/// ```rust
28
/// use wasm_encoder::{Component, InstanceSection, ExportKind, ModuleArg};
29
///
30
/// let mut instances = InstanceSection::new();
31
/// instances.export_items([("foo", ExportKind::Func, 0)]);
32
/// instances.instantiate(1, [("foo", ModuleArg::Instance(0))]);
33
///
34
/// let mut component = Component::new();
35
/// component.section(&instances);
36
///
37
/// let bytes = component.finish();
38
/// ```
39
#[derive(Clone, Debug, Default)]
40
pub struct InstanceSection {
41
    bytes: Vec<u8>,
42
    num_added: u32,
43
}
44
45
impl InstanceSection {
46
    /// Create a new core instance section encoder.
47
0
    pub fn new() -> Self {
48
0
        Self::default()
49
0
    }
50
51
    /// The number of instances in the section.
52
0
    pub fn len(&self) -> u32 {
53
0
        self.num_added
54
0
    }
55
56
    /// Determines if the section is empty.
57
0
    pub fn is_empty(&self) -> bool {
58
0
        self.num_added == 0
59
0
    }
60
61
    /// Define an instance by instantiating a core module.
62
0
    pub fn instantiate<A, S>(&mut self, module_index: u32, args: A) -> &mut Self
63
0
    where
64
0
        A: IntoIterator<Item = (S, ModuleArg)>,
65
0
        A::IntoIter: ExactSizeIterator,
66
0
        S: AsRef<str>,
67
0
    {
68
0
        let args = args.into_iter();
69
0
        self.bytes.push(0x00);
70
0
        module_index.encode(&mut self.bytes);
71
0
        args.len().encode(&mut self.bytes);
72
0
        for (name, arg) in args {
73
0
            name.as_ref().encode(&mut self.bytes);
74
0
            arg.encode(&mut self.bytes);
75
0
        }
76
0
        self.num_added += 1;
77
0
        self
78
0
    }
79
80
    /// Define an instance by exporting core WebAssembly items.
81
0
    pub fn export_items<E, S>(&mut self, exports: E) -> &mut Self
82
0
    where
83
0
        E: IntoIterator<Item = (S, ExportKind, u32)>,
84
0
        E::IntoIter: ExactSizeIterator,
85
0
        S: AsRef<str>,
86
0
    {
87
0
        let exports = exports.into_iter();
88
0
        self.bytes.push(0x01);
89
0
        exports.len().encode(&mut self.bytes);
90
0
        for (name, kind, index) in exports {
91
0
            name.as_ref().encode(&mut self.bytes);
92
0
            kind.encode(&mut self.bytes);
93
0
            index.encode(&mut self.bytes);
94
0
        }
95
0
        self.num_added += 1;
96
0
        self
97
0
    }
98
}
99
100
impl Encode for InstanceSection {
101
0
    fn encode(&self, sink: &mut Vec<u8>) {
102
0
        encode_section(sink, self.num_added, &self.bytes);
103
0
    }
104
}
105
106
impl ComponentSection for InstanceSection {
107
0
    fn id(&self) -> u8 {
108
0
        ComponentSectionId::CoreInstance.into()
109
0
    }
110
}
111
112
/// An encoder for the instance section of WebAssembly components.
113
///
114
/// # Example
115
///
116
/// ```rust
117
/// use wasm_encoder::{Component, ComponentInstanceSection, ComponentExportKind};
118
///
119
/// let mut instances = ComponentInstanceSection::new();
120
/// instances.export_items([("foo", ComponentExportKind::Func, 0)]);
121
/// instances.instantiate(1, [("foo", ComponentExportKind::Instance, 0)]);
122
///
123
/// let mut component = Component::new();
124
/// component.section(&instances);
125
///
126
/// let bytes = component.finish();
127
/// ```
128
#[derive(Clone, Debug, Default)]
129
pub struct ComponentInstanceSection {
130
    bytes: Vec<u8>,
131
    num_added: u32,
132
}
133
134
impl ComponentInstanceSection {
135
    /// Create a new instance section encoder.
136
0
    pub fn new() -> Self {
137
0
        Self::default()
138
0
    }
139
140
    /// The number of instances in the section.
141
0
    pub fn len(&self) -> u32 {
142
0
        self.num_added
143
0
    }
144
145
    /// Determines if the section is empty.
146
0
    pub fn is_empty(&self) -> bool {
147
0
        self.num_added == 0
148
0
    }
149
150
    /// Define an instance by instantiating a component.
151
0
    pub fn instantiate<A, S>(&mut self, component_index: u32, args: A) -> &mut Self
152
0
    where
153
0
        A: IntoIterator<Item = (S, ComponentExportKind, u32)>,
154
0
        A::IntoIter: ExactSizeIterator,
155
0
        S: AsRef<str>,
156
0
    {
157
0
        let args = args.into_iter();
158
0
        self.bytes.push(0x00);
159
0
        component_index.encode(&mut self.bytes);
160
0
        args.len().encode(&mut self.bytes);
161
0
        for (name, kind, index) in args {
162
0
            name.as_ref().encode(&mut self.bytes);
163
0
            kind.encode(&mut self.bytes);
164
0
            index.encode(&mut self.bytes);
165
0
        }
166
0
        self.num_added += 1;
167
0
        self
168
0
    }
169
170
    /// Define an instance by exporting items.
171
0
    pub fn export_items<'a, E>(&mut self, exports: E) -> &mut Self
172
0
    where
173
0
        E: IntoIterator<Item = (&'a str, ComponentExportKind, u32)>,
174
0
        E::IntoIter: ExactSizeIterator,
175
0
    {
176
0
        let exports = exports.into_iter();
177
0
        self.bytes.push(0x01);
178
0
        exports.len().encode(&mut self.bytes);
179
0
        for (name, kind, index) in exports {
180
0
            crate::push_extern_name_byte(&mut self.bytes, name);
181
0
            name.encode(&mut self.bytes);
182
0
            kind.encode(&mut self.bytes);
183
0
            index.encode(&mut self.bytes);
184
0
        }
185
0
        self.num_added += 1;
186
0
        self
187
0
    }
188
}
189
190
impl Encode for ComponentInstanceSection {
191
0
    fn encode(&self, sink: &mut Vec<u8>) {
192
0
        encode_section(sink, self.num_added, &self.bytes);
193
0
    }
194
}
195
196
impl ComponentSection for ComponentInstanceSection {
197
0
    fn id(&self) -> u8 {
198
0
        ComponentSectionId::Instance.into()
199
0
    }
200
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/modules.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{ComponentSection, ComponentSectionId, Encode, Module};
2
3
/// An encoder for the module section of WebAssembly components.
4
///
5
/// # Example
6
///
7
/// ```rust
8
/// use wasm_encoder::{Module, Component, ModuleSection};
9
///
10
/// let mut module = Module::new();
11
/// let mut component = Component::new();
12
/// component.section(&ModuleSection(&module));
13
///
14
/// let bytes = component.finish();
15
/// ```
16
#[derive(Clone, Debug)]
17
pub struct ModuleSection<'a>(pub &'a Module);
18
19
impl Encode for ModuleSection<'_> {
20
0
    fn encode(&self, sink: &mut Vec<u8>) {
21
0
        self.0.bytes.encode(sink);
22
0
    }
23
}
24
25
impl ComponentSection for ModuleSection<'_> {
26
0
    fn id(&self) -> u8 {
27
0
        ComponentSectionId::CoreModule.into()
28
0
    }
29
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/names.rs
Line
Count
Source (jump to first uncovered line)
1
use std::borrow::Cow;
2
3
use super::*;
4
use crate::{encoding_size, ExportKind, NameMap, SectionId};
5
6
/// Encoding for the `component-name` custom section which assigns
7
/// human-readable names to items within a component.
8
#[derive(Clone, Debug, Default)]
9
pub struct ComponentNameSection {
10
    bytes: Vec<u8>,
11
}
12
13
enum Subsection {
14
    Component,
15
    Decls,
16
}
17
18
impl ComponentNameSection {
19
    /// Creates a new blank `name` custom section.
20
0
    pub fn new() -> Self {
21
0
        Self::default()
22
0
    }
23
24
    /// Appends a component name subsection to this section.
25
    ///
26
    /// This will indicate that the name of the entire component should be the
27
    /// `name` specified. Note that this should be encoded first before other
28
    /// subsections.
29
0
    pub fn component(&mut self, name: &str) {
30
0
        let len = encoding_size(u32::try_from(name.len()).unwrap());
31
0
        self.subsection_header(Subsection::Component, len + name.len());
32
0
        name.encode(&mut self.bytes);
33
0
    }
34
35
    /// Appends a decls name subsection to name core functions within the
36
    /// component.
37
0
    pub fn core_funcs(&mut self, names: &NameMap) {
38
0
        self.core_decls(ExportKind::Func as u8, names)
39
0
    }
40
41
    /// Appends a decls name subsection to name core tables within the
42
    /// component.
43
0
    pub fn core_tables(&mut self, names: &NameMap) {
44
0
        self.core_decls(ExportKind::Table as u8, names)
45
0
    }
46
47
    /// Appends a decls name subsection to name core memories within the
48
    /// component.
49
0
    pub fn core_memories(&mut self, names: &NameMap) {
50
0
        self.core_decls(ExportKind::Memory as u8, names)
51
0
    }
52
53
    /// Appends a decls name subsection to name core globals within the
54
    /// component.
55
0
    pub fn core_globals(&mut self, names: &NameMap) {
56
0
        self.core_decls(ExportKind::Global as u8, names)
57
0
    }
58
59
    /// Appends a decls name subsection to name core types within the
60
    /// component.
61
0
    pub fn core_types(&mut self, names: &NameMap) {
62
0
        self.core_decls(CORE_TYPE_SORT, names)
63
0
    }
64
65
    /// Appends a decls name subsection to name core modules within the
66
    /// component.
67
0
    pub fn core_modules(&mut self, names: &NameMap) {
68
0
        self.core_decls(CORE_MODULE_SORT, names)
69
0
    }
70
71
    /// Appends a decls name subsection to name core instances within the
72
    /// component.
73
0
    pub fn core_instances(&mut self, names: &NameMap) {
74
0
        self.core_decls(CORE_INSTANCE_SORT, names)
75
0
    }
76
77
    /// Appends a decls name subsection to name component functions within the
78
    /// component.
79
0
    pub fn funcs(&mut self, names: &NameMap) {
80
0
        self.component_decls(FUNCTION_SORT, names)
81
0
    }
82
83
    /// Appends a decls name subsection to name component values within the
84
    /// component.
85
0
    pub fn values(&mut self, names: &NameMap) {
86
0
        self.component_decls(VALUE_SORT, names)
87
0
    }
88
89
    /// Appends a decls name subsection to name component type within the
90
    /// component.
91
0
    pub fn types(&mut self, names: &NameMap) {
92
0
        self.component_decls(TYPE_SORT, names)
93
0
    }
94
95
    /// Appends a decls name subsection to name components within the
96
    /// component.
97
0
    pub fn components(&mut self, names: &NameMap) {
98
0
        self.component_decls(COMPONENT_SORT, names)
99
0
    }
100
101
    /// Appends a decls name subsection to name component instances within the
102
    /// component.
103
0
    pub fn instances(&mut self, names: &NameMap) {
104
0
        self.component_decls(INSTANCE_SORT, names)
105
0
    }
106
107
0
    fn component_decls(&mut self, kind: u8, names: &NameMap) {
108
0
        self.subsection_header(Subsection::Decls, 1 + names.size());
109
0
        self.bytes.push(kind);
110
0
        names.encode(&mut self.bytes);
111
0
    }
112
113
0
    fn core_decls(&mut self, kind: u8, names: &NameMap) {
114
0
        self.subsection_header(Subsection::Decls, 2 + names.size());
115
0
        self.bytes.push(CORE_SORT);
116
0
        self.bytes.push(kind);
117
0
        names.encode(&mut self.bytes);
118
0
    }
119
120
0
    fn subsection_header(&mut self, id: Subsection, len: usize) {
121
0
        self.bytes.push(id as u8);
122
0
        len.encode(&mut self.bytes);
123
0
    }
124
125
    /// Returns whether this section is empty, or nothing has been encoded.
126
0
    pub fn is_empty(&self) -> bool {
127
0
        self.bytes.is_empty()
128
0
    }
129
130
    /// View the encoded section as a CustomSection.
131
0
    pub fn as_custom<'a>(&'a self) -> CustomSection<'a> {
132
0
        CustomSection {
133
0
            name: "component-name".into(),
134
0
            data: Cow::Borrowed(&self.bytes),
135
0
        }
136
0
    }
137
}
138
139
impl Encode for ComponentNameSection {
140
0
    fn encode(&self, sink: &mut Vec<u8>) {
141
0
        self.as_custom().encode(sink);
142
0
    }
143
}
144
145
impl ComponentSection for ComponentNameSection {
146
0
    fn id(&self) -> u8 {
147
0
        SectionId::Custom.into()
148
0
    }
149
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/start.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{ComponentSection, ComponentSectionId, Encode};
2
3
/// An encoder for the start section of WebAssembly components.
4
///
5
/// # Example
6
///
7
/// ```
8
/// use wasm_encoder::{Component, ComponentStartSection};
9
///
10
/// let start = ComponentStartSection { function_index: 0, args: [0, 1], results: 1 };
11
///
12
/// let mut component = Component::new();
13
/// component.section(&start);
14
///
15
/// let bytes = component.finish();
16
/// ```
17
#[derive(Clone, Debug)]
18
pub struct ComponentStartSection<A> {
19
    /// The index to the start function.
20
    pub function_index: u32,
21
    /// The arguments to pass to the start function.
22
    ///
23
    /// An argument is an index to a value.
24
    pub args: A,
25
    /// The number of expected results for the start function.
26
    ///
27
    /// This should match the number of results for the type of
28
    /// the function referenced by `function_index`.
29
    pub results: u32,
30
}
31
32
impl<A> Encode for ComponentStartSection<A>
33
where
34
    A: AsRef<[u32]>,
35
{
36
0
    fn encode(&self, sink: &mut Vec<u8>) {
37
0
        let mut bytes = Vec::new();
38
0
        self.function_index.encode(&mut bytes);
39
0
        self.args.as_ref().encode(&mut bytes);
40
0
        self.results.encode(&mut bytes);
41
0
        bytes.encode(sink);
42
0
    }
43
}
44
45
impl<A> ComponentSection for ComponentStartSection<A>
46
where
47
    A: AsRef<[u32]>,
48
{
49
0
    fn id(&self) -> u8 {
50
0
        ComponentSectionId::Start.into()
51
0
    }
52
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/component/types.rs
Line
Count
Source (jump to first uncovered line)
1
use super::CORE_TYPE_SORT;
2
use crate::{
3
    encode_section, Alias, ComponentExportKind, ComponentOuterAliasKind, ComponentSection,
4
    ComponentSectionId, ComponentTypeRef, Encode, EntityType, ValType,
5
};
6
7
/// Represents the type of a core module.
8
#[derive(Debug, Clone, Default)]
9
pub struct ModuleType {
10
    bytes: Vec<u8>,
11
    num_added: u32,
12
    types_added: u32,
13
}
14
15
impl ModuleType {
16
    /// Creates a new core module type.
17
0
    pub fn new() -> Self {
18
0
        Self::default()
19
0
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB2_10ModuleType3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB2_10ModuleType3newB6_
20
21
    /// Defines an import in this module type.
22
0
    pub fn import(&mut self, module: &str, name: &str, ty: EntityType) -> &mut Self {
23
0
        crate::component::imports::push_extern_name_byte(&mut self.bytes, name);
24
0
        module.encode(&mut self.bytes);
25
0
        name.encode(&mut self.bytes);
26
0
        ty.encode(&mut self.bytes);
27
0
        self.num_added += 1;
28
0
        self
29
0
    }
30
31
    /// Define a type in this module type.
32
    ///
33
    /// The returned encoder must be used before adding another definition.
34
    #[must_use = "the encoder must be used to encode the type"]
35
0
    pub fn ty(&mut self) -> CoreTypeEncoder {
36
0
        self.bytes.push(0x01);
37
0
        self.num_added += 1;
38
0
        self.types_added += 1;
39
0
        CoreTypeEncoder(&mut self.bytes)
40
0
    }
41
42
    /// Defines an outer core type alias in this module type.
43
0
    pub fn alias_outer_core_type(&mut self, count: u32, index: u32) -> &mut Self {
44
0
        self.bytes.push(0x02);
45
0
        self.bytes.push(CORE_TYPE_SORT);
46
0
        self.bytes.push(0x01); // outer
47
0
        count.encode(&mut self.bytes);
48
0
        index.encode(&mut self.bytes);
49
0
        self.num_added += 1;
50
0
        self.types_added += 1;
51
0
        self
52
0
    }
53
54
    /// Defines an export in this module type.
55
0
    pub fn export(&mut self, name: &str, ty: EntityType) -> &mut Self {
56
0
        self.bytes.push(0x03);
57
0
        name.encode(&mut self.bytes);
58
0
        ty.encode(&mut self.bytes);
59
0
        self.num_added += 1;
60
0
        self
61
0
    }
62
63
    /// Gets the number of types that have been added to this module type.
64
0
    pub fn type_count(&self) -> u32 {
65
0
        self.types_added
66
0
    }
67
}
68
69
impl Encode for ModuleType {
70
0
    fn encode(&self, sink: &mut Vec<u8>) {
71
0
        sink.push(0x50);
72
0
        self.num_added.encode(sink);
73
0
        sink.extend(&self.bytes);
74
0
    }
75
}
76
77
/// Used to encode core types.
78
#[derive(Debug)]
79
pub struct CoreTypeEncoder<'a>(pub(crate) &'a mut Vec<u8>);
80
81
impl<'a> CoreTypeEncoder<'a> {
82
    /// Define a function type.
83
0
    pub fn function<P, R>(self, params: P, results: R)
84
0
    where
85
0
        P: IntoIterator<Item = ValType>,
86
0
        P::IntoIter: ExactSizeIterator,
87
0
        R: IntoIterator<Item = ValType>,
88
0
        R::IntoIter: ExactSizeIterator,
89
0
    {
90
0
        let params = params.into_iter();
91
0
        let results = results.into_iter();
92
0
93
0
        self.0.push(0x60);
94
0
        params.len().encode(self.0);
95
0
        params.for_each(|p| p.encode(self.0));
Unexecuted instantiation: _RNCINvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB8_15CoreTypeEncoder8functionINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1y_5slice4iter4IterNtNtNtBc_4core5types7ValTypeEEB1p_E0Cs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNCINvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB8_15CoreTypeEncoder8functionppE0Bc_
96
0
        results.len().encode(self.0);
97
0
        results.for_each(|p| p.encode(self.0));
Unexecuted instantiation: _RNCINvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB8_15CoreTypeEncoder8functionINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1y_5slice4iter4IterNtNtNtBc_4core5types7ValTypeEEB1p_Es_0Cs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNCINvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB8_15CoreTypeEncoder8functionppEs_0Bc_
98
0
    }
Unexecuted instantiation: _RINvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_15CoreTypeEncoder8functionINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1w_5slice4iter4IterNtNtNtBa_4core5types7ValTypeEEB1n_ECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_15CoreTypeEncoder8functionppEBa_
99
100
    /// Define a module type.
101
0
    pub fn module(self, ty: &ModuleType) {
102
0
        ty.encode(self.0);
103
0
    }
104
}
105
106
/// An encoder for the core type section of WebAssembly components.
107
///
108
/// # Example
109
///
110
/// ```rust
111
/// use wasm_encoder::{Component, CoreTypeSection, ModuleType};
112
///
113
/// let mut types = CoreTypeSection::new();
114
///
115
/// types.module(&ModuleType::new());
116
///
117
/// let mut component = Component::new();
118
/// component.section(&types);
119
///
120
/// let bytes = component.finish();
121
/// ```
122
#[derive(Clone, Debug, Default)]
123
pub struct CoreTypeSection {
124
    bytes: Vec<u8>,
125
    num_added: u32,
126
}
127
128
impl CoreTypeSection {
129
    /// Create a new core type section encoder.
130
0
    pub fn new() -> Self {
131
0
        Self::default()
132
0
    }
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_15CoreTypeSection3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_15CoreTypeSection3newB9_
133
134
    /// The number of types in the section.
135
0
    pub fn len(&self) -> u32 {
136
0
        self.num_added
137
0
    }
138
139
    /// Determines if the section is empty.
140
0
    pub fn is_empty(&self) -> bool {
141
0
        self.num_added == 0
142
0
    }
143
144
    /// Encode a type into this section.
145
    ///
146
    /// The returned encoder must be finished before adding another type.
147
    #[must_use = "the encoder must be used to encode the type"]
148
0
    pub fn ty(&mut self) -> CoreTypeEncoder<'_> {
149
0
        self.num_added += 1;
150
0
        CoreTypeEncoder(&mut self.bytes)
151
0
    }
152
153
    /// Define a function type in this type section.
154
0
    pub fn function<P, R>(&mut self, params: P, results: R) -> &mut Self
155
0
    where
156
0
        P: IntoIterator<Item = ValType>,
157
0
        P::IntoIter: ExactSizeIterator,
158
0
        R: IntoIterator<Item = ValType>,
159
0
        R::IntoIter: ExactSizeIterator,
160
0
    {
161
0
        self.ty().function(params, results);
162
0
        self
163
0
    }
164
165
    /// Define a module type in this type section.
166
    ///
167
    /// Currently this is only used for core type sections in components.
168
0
    pub fn module(&mut self, ty: &ModuleType) -> &mut Self {
169
0
        self.ty().module(ty);
170
0
        self
171
0
    }
172
}
173
174
impl Encode for CoreTypeSection {
175
0
    fn encode(&self, sink: &mut Vec<u8>) {
176
0
        encode_section(sink, self.num_added, &self.bytes);
177
0
    }
178
}
179
180
impl ComponentSection for CoreTypeSection {
181
0
    fn id(&self) -> u8 {
182
0
        ComponentSectionId::CoreType.into()
183
0
    }
Unexecuted instantiation: _RNvXs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_15CoreTypeSectionNtB7_16ComponentSection2idCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_15CoreTypeSectionNtB7_16ComponentSection2idB9_
184
}
185
186
/// Represents a component type.
187
#[derive(Debug, Clone, Default)]
188
pub struct ComponentType {
189
    bytes: Vec<u8>,
190
    num_added: u32,
191
    core_types_added: u32,
192
    types_added: u32,
193
    instances_added: u32,
194
}
195
196
impl ComponentType {
197
    /// Creates a new component type.
198
0
    pub fn new() -> Self {
199
0
        Self::default()
200
0
    }
Unexecuted instantiation: _RNvMs4_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_13ComponentType3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs4_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_13ComponentType3newB9_
201
202
    /// Define a core type in this component type.
203
    ///
204
    /// The returned encoder must be used before adding another definition.
205
    #[must_use = "the encoder must be used to encode the type"]
206
0
    pub fn core_type(&mut self) -> CoreTypeEncoder {
207
0
        self.bytes.push(0x00);
208
0
        self.num_added += 1;
209
0
        self.core_types_added += 1;
210
0
        CoreTypeEncoder(&mut self.bytes)
211
0
    }
212
213
    /// Define a type in this component type.
214
    ///
215
    /// The returned encoder must be used before adding another definition.
216
    #[must_use = "the encoder must be used to encode the type"]
217
0
    pub fn ty(&mut self) -> ComponentTypeEncoder {
218
0
        self.bytes.push(0x01);
219
0
        self.num_added += 1;
220
0
        self.types_added += 1;
221
0
        ComponentTypeEncoder(&mut self.bytes)
222
0
    }
223
224
    /// Defines an alias for an exported item of a prior instance or an
225
    /// outer type.
226
0
    pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
227
0
        self.bytes.push(0x02);
228
0
        alias.encode(&mut self.bytes);
229
0
        self.num_added += 1;
230
0
        match &alias {
231
            Alias::InstanceExport {
232
                kind: ComponentExportKind::Type,
233
                ..
234
            }
235
            | Alias::Outer {
236
                kind: ComponentOuterAliasKind::Type,
237
                ..
238
0
            } => self.types_added += 1,
239
            Alias::Outer {
240
                kind: ComponentOuterAliasKind::CoreType,
241
                ..
242
0
            } => self.core_types_added += 1,
243
            Alias::InstanceExport {
244
                kind: ComponentExportKind::Instance,
245
                ..
246
0
            } => self.instances_added += 1,
247
0
            _ => {}
248
        }
249
0
        self
250
0
    }
251
252
    /// Defines an import in this component type.
253
0
    pub fn import(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
254
0
        self.bytes.push(0x03);
255
0
        crate::component::imports::push_extern_name_byte(&mut self.bytes, name);
256
0
        name.encode(&mut self.bytes);
257
0
        ty.encode(&mut self.bytes);
258
0
        self.num_added += 1;
259
0
        match ty {
260
0
            ComponentTypeRef::Type(..) => self.types_added += 1,
261
0
            ComponentTypeRef::Instance(..) => self.instances_added += 1,
262
0
            _ => {}
263
        }
264
0
        self
265
0
    }
266
267
    /// Defines an export in this component type.
268
0
    pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
269
0
        self.bytes.push(0x04);
270
0
        crate::component::imports::push_extern_name_byte(&mut self.bytes, name);
271
0
        name.encode(&mut self.bytes);
272
0
        ty.encode(&mut self.bytes);
273
0
        self.num_added += 1;
274
0
        match ty {
275
0
            ComponentTypeRef::Type(..) => self.types_added += 1,
276
0
            ComponentTypeRef::Instance(..) => self.instances_added += 1,
277
0
            _ => {}
278
        }
279
0
        self
280
0
    }
281
282
    /// Gets the number of core types that have been added to this component type.
283
0
    pub fn core_type_count(&self) -> u32 {
284
0
        self.core_types_added
285
0
    }
286
287
    /// Gets the number of types that have been added or aliased in this component type.
288
0
    pub fn type_count(&self) -> u32 {
289
0
        self.types_added
290
0
    }
291
292
    /// Gets the number of instances that have been defined in this component
293
    /// type through imports, exports, or aliases.
294
0
    pub fn instance_count(&self) -> u32 {
295
0
        self.instances_added
296
0
    }
297
}
298
299
impl Encode for ComponentType {
300
0
    fn encode(&self, sink: &mut Vec<u8>) {
301
0
        sink.push(0x41);
302
0
        self.num_added.encode(sink);
303
0
        sink.extend(&self.bytes);
304
0
    }
305
}
306
307
/// Represents an instance type.
308
#[derive(Debug, Clone, Default)]
309
pub struct InstanceType(ComponentType);
310
311
impl InstanceType {
312
    /// Creates a new instance type.
313
0
    pub fn new() -> Self {
314
0
        Self::default()
315
0
    }
Unexecuted instantiation: _RNvMs6_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_12InstanceType3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs6_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_12InstanceType3newB9_
316
317
    /// Define a core type in this instance type.
318
    ///
319
    /// The returned encoder must be used before adding another definition.
320
    #[must_use = "the encoder must be used to encode the type"]
321
0
    pub fn core_type(&mut self) -> CoreTypeEncoder {
322
0
        self.0.core_type()
323
0
    }
324
325
    /// Define a type in this instance type.
326
    ///
327
    /// The returned encoder must be used before adding another definition.
328
    #[must_use = "the encoder must be used to encode the type"]
329
0
    pub fn ty(&mut self) -> ComponentTypeEncoder {
330
0
        self.0.ty()
331
0
    }
332
333
    /// Defines an outer core type alias in this component type.
334
0
    pub fn alias(&mut self, alias: Alias<'_>) -> &mut Self {
335
0
        self.0.alias(alias);
336
0
        self
337
0
    }
338
339
    /// Defines an export in this instance type.
340
0
    pub fn export(&mut self, name: &str, ty: ComponentTypeRef) -> &mut Self {
341
0
        self.0.export(name, ty);
342
0
        self
343
0
    }
344
345
    /// Gets the number of core types that have been added to this instance type.
346
0
    pub fn core_type_count(&self) -> u32 {
347
0
        self.0.core_types_added
348
0
    }
349
350
    /// Gets the number of types that have been added or aliased in this instance type.
351
0
    pub fn type_count(&self) -> u32 {
352
0
        self.0.types_added
353
0
    }
354
355
    /// Gets the number of instances that have been imported or exported or
356
    /// aliased in this instance type.
357
0
    pub fn instance_count(&self) -> u32 {
358
0
        self.0.instances_added
359
0
    }
360
361
    /// Returns whether or not this instance type is empty.
362
0
    pub fn is_empty(&self) -> bool {
363
0
        self.0.num_added == 0
364
0
    }
365
366
    /// Returns the number of entries added to this instance types.
367
0
    pub fn len(&self) -> u32 {
368
0
        self.0.num_added
369
0
    }
370
}
371
372
impl Encode for InstanceType {
373
0
    fn encode(&self, sink: &mut Vec<u8>) {
374
0
        sink.push(0x42);
375
0
        self.0.num_added.encode(sink);
376
0
        sink.extend(&self.0.bytes);
377
0
    }
378
}
379
380
/// Used to encode component function types.
381
#[derive(Debug)]
382
pub struct ComponentFuncTypeEncoder<'a>(&'a mut Vec<u8>);
383
384
impl<'a> ComponentFuncTypeEncoder<'a> {
385
0
    fn new(sink: &'a mut Vec<u8>) -> Self {
386
0
        sink.push(0x40);
387
0
        Self(sink)
388
0
    }
389
390
    /// Defines named parameters.
391
    ///
392
    /// Parameters must be defined before defining results.
393
0
    pub fn params<'b, P, T>(&mut self, params: P) -> &mut Self
394
0
    where
395
0
        P: IntoIterator<Item = (&'b str, T)>,
396
0
        P::IntoIter: ExactSizeIterator,
397
0
        T: Into<ComponentValType>,
398
0
    {
399
0
        let params = params.into_iter();
400
0
        params.len().encode(self.0);
401
0
        for (name, ty) in params {
402
0
            name.encode(self.0);
403
0
            ty.into().encode(self.0);
404
0
        }
405
0
        self
406
0
    }
Unexecuted instantiation: _RINvMs8_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_24ComponentFuncTypeEncoder6paramsINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1D_5slice4iter4IterTNtNtCsbpSlAbJY2yh_5alloc6string6StringNtB6_16ComponentValTypeEENCNvMs6_NtNtCs4eJdYXiOSk9_10wasm_smith9component6encodeNtB3V_4Type6encode0EB3m_EB3X_
Unexecuted instantiation: _RINvMs8_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_24ComponentFuncTypeEncoder6paramsppEBa_
407
408
    /// Defines a single unnamed result.
409
    ///
410
    /// This method cannot be used with `results`.
411
0
    pub fn result(&mut self, ty: impl Into<ComponentValType>) -> &mut Self {
412
0
        self.0.push(0x00);
413
0
        ty.into().encode(self.0);
414
0
        self
415
0
    }
Unexecuted instantiation: _RINvMs8_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_24ComponentFuncTypeEncoder6resultNtB6_16ComponentValTypeECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs8_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_24ComponentFuncTypeEncoder6resultpEBa_
416
417
    /// Defines named results.
418
    ///
419
    /// This method cannot be used with `result`.
420
0
    pub fn results<'b, R, T>(&mut self, results: R) -> &mut Self
421
0
    where
422
0
        R: IntoIterator<Item = (&'b str, T)>,
423
0
        R::IntoIter: ExactSizeIterator,
424
0
        T: Into<ComponentValType>,
425
0
    {
426
0
        self.0.push(0x01);
427
0
        let results = results.into_iter();
428
0
        results.len().encode(self.0);
429
0
        for (name, ty) in results {
430
0
            name.encode(self.0);
431
0
            ty.into().encode(self.0);
432
0
        }
433
0
        self
434
0
    }
Unexecuted instantiation: _RINvMs8_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_24ComponentFuncTypeEncoder7resultsINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1E_5slice4iter4IterTINtNtB1E_6option6OptionNtNtCsbpSlAbJY2yh_5alloc6string6StringENtB6_16ComponentValTypeEENCNvMs6_NtNtCs4eJdYXiOSk9_10wasm_smith9component6encodeNtB4k_4Type6encodes_0EB3L_EB4m_
Unexecuted instantiation: _RINvMs8_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_24ComponentFuncTypeEncoder7resultsppEBa_
435
}
436
437
/// Used to encode component and instance types.
438
#[derive(Debug)]
439
pub struct ComponentTypeEncoder<'a>(&'a mut Vec<u8>);
440
441
impl<'a> ComponentTypeEncoder<'a> {
442
    /// Define a component type.
443
0
    pub fn component(self, ty: &ComponentType) {
444
0
        ty.encode(self.0);
445
0
    }
446
447
    /// Define an instance type.
448
0
    pub fn instance(self, ty: &InstanceType) {
449
0
        ty.encode(self.0);
450
0
    }
451
452
    /// Define a function type.
453
0
    pub fn function(self) -> ComponentFuncTypeEncoder<'a> {
454
0
        ComponentFuncTypeEncoder::new(self.0)
455
0
    }
456
457
    /// Define a defined component type.
458
    ///
459
    /// The returned encoder must be used before adding another type.
460
    #[must_use = "the encoder must be used to encode the type"]
461
0
    pub fn defined_type(self) -> ComponentDefinedTypeEncoder<'a> {
462
0
        ComponentDefinedTypeEncoder(self.0)
463
0
    }
Unexecuted instantiation: _RNvMs9_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_20ComponentTypeEncoder12defined_typeCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs9_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_20ComponentTypeEncoder12defined_typeB9_
464
465
    /// Define a resource type.
466
0
    pub fn resource(self, rep: ValType, dtor: Option<u32>) {
467
0
        self.0.push(0x3f);
468
0
        rep.encode(self.0);
469
0
        match dtor {
470
0
            Some(i) => {
471
0
                self.0.push(0x01);
472
0
                i.encode(self.0);
473
0
            }
474
0
            None => self.0.push(0x00),
475
        }
476
0
    }
477
}
478
479
/// Represents a primitive component value type.
480
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
481
pub enum PrimitiveValType {
482
    /// The type is a boolean.
483
    Bool,
484
    /// The type is a signed 8-bit integer.
485
    S8,
486
    /// The type is an unsigned 8-bit integer.
487
    U8,
488
    /// The type is a signed 16-bit integer.
489
    S16,
490
    /// The type is an unsigned 16-bit integer.
491
    U16,
492
    /// The type is a signed 32-bit integer.
493
    S32,
494
    /// The type is an unsigned 32-bit integer.
495
    U32,
496
    /// The type is a signed 64-bit integer.
497
    S64,
498
    /// The type is an unsigned 64-bit integer.
499
    U64,
500
    /// The type is a 32-bit floating point number with only one NaN.
501
    F32,
502
    /// The type is a 64-bit floating point number with only one NaN.
503
    F64,
504
    /// The type is a Unicode character.
505
    Char,
506
    /// The type is a string.
507
    String,
508
}
509
510
impl Encode for PrimitiveValType {
511
0
    fn encode(&self, sink: &mut Vec<u8>) {
512
0
        sink.push(match self {
513
0
            Self::Bool => 0x7f,
514
0
            Self::S8 => 0x7e,
515
0
            Self::U8 => 0x7d,
516
0
            Self::S16 => 0x7c,
517
0
            Self::U16 => 0x7b,
518
0
            Self::S32 => 0x7a,
519
0
            Self::U32 => 0x79,
520
0
            Self::S64 => 0x78,
521
0
            Self::U64 => 0x77,
522
0
            Self::F32 => 0x76,
523
0
            Self::F64 => 0x75,
524
0
            Self::Char => 0x74,
525
0
            Self::String => 0x73,
526
        });
527
0
    }
528
}
529
530
#[cfg(feature = "wasmparser")]
531
impl From<wasmparser::PrimitiveValType> for PrimitiveValType {
532
    fn from(ty: wasmparser::PrimitiveValType) -> Self {
533
        match ty {
534
            wasmparser::PrimitiveValType::Bool => PrimitiveValType::Bool,
535
            wasmparser::PrimitiveValType::S8 => PrimitiveValType::S8,
536
            wasmparser::PrimitiveValType::U8 => PrimitiveValType::U8,
537
            wasmparser::PrimitiveValType::S16 => PrimitiveValType::S16,
538
            wasmparser::PrimitiveValType::U16 => PrimitiveValType::U16,
539
            wasmparser::PrimitiveValType::S32 => PrimitiveValType::S32,
540
            wasmparser::PrimitiveValType::U32 => PrimitiveValType::U32,
541
            wasmparser::PrimitiveValType::S64 => PrimitiveValType::S64,
542
            wasmparser::PrimitiveValType::U64 => PrimitiveValType::U64,
543
            wasmparser::PrimitiveValType::F32 => PrimitiveValType::F32,
544
            wasmparser::PrimitiveValType::F64 => PrimitiveValType::F64,
545
            wasmparser::PrimitiveValType::Char => PrimitiveValType::Char,
546
            wasmparser::PrimitiveValType::String => PrimitiveValType::String,
547
        }
548
    }
549
}
550
551
/// Represents a component value type.
552
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
553
pub enum ComponentValType {
554
    /// The value is a primitive type.
555
    Primitive(PrimitiveValType),
556
    /// The value is to a defined value type.
557
    ///
558
    /// The type index must be to a value type.
559
    Type(u32),
560
}
561
562
impl Encode for ComponentValType {
563
0
    fn encode(&self, sink: &mut Vec<u8>) {
564
0
        match self {
565
0
            Self::Primitive(ty) => ty.encode(sink),
566
0
            Self::Type(index) => (*index as i64).encode(sink),
567
        }
568
0
    }
569
}
570
571
impl From<PrimitiveValType> for ComponentValType {
572
0
    fn from(ty: PrimitiveValType) -> Self {
573
0
        Self::Primitive(ty)
574
0
    }
575
}
576
577
/// Used for encoding component defined types.
578
#[derive(Debug)]
579
pub struct ComponentDefinedTypeEncoder<'a>(&'a mut Vec<u8>);
580
581
impl ComponentDefinedTypeEncoder<'_> {
582
    /// Define a primitive value type.
583
0
    pub fn primitive(self, ty: PrimitiveValType) {
584
0
        ty.encode(self.0);
585
0
    }
586
587
    /// Define a record type.
588
0
    pub fn record<'a, F, T>(self, fields: F)
589
0
    where
590
0
        F: IntoIterator<Item = (&'a str, T)>,
591
0
        F::IntoIter: ExactSizeIterator,
592
0
        T: Into<ComponentValType>,
593
0
    {
594
0
        let fields = fields.into_iter();
595
0
        self.0.push(0x72);
596
0
        fields.len().encode(self.0);
597
0
        for (name, ty) in fields {
598
0
            name.encode(self.0);
599
0
            ty.into().encode(self.0);
600
0
        }
601
0
    }
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder6recordINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1G_5slice4iter4IterTNtNtCsbpSlAbJY2yh_5alloc6string6StringNtB6_16ComponentValTypeEENCNvMs7_NtNtCs4eJdYXiOSk9_10wasm_smith9component6encodeNtB3Y_11DefinedType6encode0EB3p_EB40_
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder6recordppEBa_
602
603
    /// Define a variant type.
604
0
    pub fn variant<'a, C>(self, cases: C)
605
0
    where
606
0
        C: IntoIterator<Item = (&'a str, Option<ComponentValType>, Option<u32>)>,
607
0
        C::IntoIter: ExactSizeIterator,
608
0
    {
609
0
        let cases = cases.into_iter();
610
0
        self.0.push(0x71);
611
0
        cases.len().encode(self.0);
612
0
        for (name, ty, refines) in cases {
613
0
            name.encode(self.0);
614
0
            ty.encode(self.0);
615
0
            refines.encode(self.0);
616
0
        }
617
0
    }
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder7variantINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1H_5slice4iter4IterTNtNtCsbpSlAbJY2yh_5alloc6string6StringINtNtB1H_6option6OptionNtB6_16ComponentValTypeEIB3r_mEEENCNvMs7_NtNtCs4eJdYXiOSk9_10wasm_smith9component6encodeNtB4u_11DefinedType6encodes_0EEB4w_
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder7variantpEBa_
618
619
    /// Define a list type.
620
0
    pub fn list(self, ty: impl Into<ComponentValType>) {
621
0
        self.0.push(0x70);
622
0
        ty.into().encode(self.0);
623
0
    }
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder4listNtB6_16ComponentValTypeECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder4listpEBa_
624
625
    /// Define a tuple type.
626
0
    pub fn tuple<I, T>(self, types: I)
627
0
    where
628
0
        I: IntoIterator<Item = T>,
629
0
        I::IntoIter: ExactSizeIterator,
630
0
        T: Into<ComponentValType>,
631
0
    {
632
0
        let types = types.into_iter();
633
0
        self.0.push(0x6F);
634
0
        types.len().encode(self.0);
635
0
        for ty in types {
636
0
            ty.into().encode(self.0);
637
0
        }
638
0
    }
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder5tupleINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1F_5slice4iter4IterNtB6_16ComponentValTypeEEB2R_ECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder5tupleppEBa_
639
640
    /// Define a flags type.
641
0
    pub fn flags<'a, I>(self, names: I)
642
0
    where
643
0
        I: IntoIterator<Item = &'a str>,
644
0
        I::IntoIter: ExactSizeIterator,
645
0
    {
646
0
        let names = names.into_iter();
647
0
        self.0.push(0x6E);
648
0
        names.len().encode(self.0);
649
0
        for name in names {
650
0
            name.encode(self.0);
651
0
        }
652
0
    }
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder5flagsINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1F_5slice4iter4IterNtNtCsbpSlAbJY2yh_5alloc6string6StringENCNvMs7_NtNtCs4eJdYXiOSk9_10wasm_smith9component6encodeNtB3y_11DefinedType6encodes0_0EEB3A_
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder5flagspEBa_
653
654
    /// Define an enum type.
655
0
    pub fn enum_type<'a, I>(self, tags: I)
656
0
    where
657
0
        I: IntoIterator<Item = &'a str>,
658
0
        I::IntoIter: ExactSizeIterator,
659
0
    {
660
0
        let tags = tags.into_iter();
661
0
        self.0.push(0x6D);
662
0
        tags.len().encode(self.0);
663
0
        for tag in tags {
664
0
            tag.encode(self.0);
665
0
        }
666
0
    }
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder9enum_typeINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1J_5slice4iter4IterNtNtCsbpSlAbJY2yh_5alloc6string6StringENCNvMs7_NtNtCs4eJdYXiOSk9_10wasm_smith9component6encodeNtB3C_11DefinedType6encodes1_0EEB3E_
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder9enum_typepEBa_
667
668
    /// Define an option type.
669
0
    pub fn option(self, ty: impl Into<ComponentValType>) {
670
0
        self.0.push(0x6B);
671
0
        ty.into().encode(self.0);
672
0
    }
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder6optionNtB6_16ComponentValTypeECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMsd_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB6_27ComponentDefinedTypeEncoder6optionpEBa_
673
674
    /// Define a result type.
675
0
    pub fn result(self, ok: Option<ComponentValType>, err: Option<ComponentValType>) {
676
0
        self.0.push(0x6A);
677
0
        ok.encode(self.0);
678
0
        err.encode(self.0);
679
0
    }
680
681
    /// Define a `own` handle type
682
0
    pub fn own(self, idx: u32) {
683
0
        self.0.push(0x69);
684
0
        idx.encode(self.0);
685
0
    }
686
687
    /// Define a `borrow` handle type
688
0
    pub fn borrow(self, idx: u32) {
689
0
        self.0.push(0x68);
690
0
        idx.encode(self.0);
691
0
    }
692
}
693
694
/// An encoder for the type section of WebAssembly components.
695
///
696
/// # Example
697
///
698
/// ```rust
699
/// use wasm_encoder::{Component, ComponentTypeSection, PrimitiveValType};
700
///
701
/// let mut types = ComponentTypeSection::new();
702
///
703
/// // Define a function type of `[string, string] -> string`.
704
/// types
705
///   .function()
706
///   .params(
707
///     [
708
///       ("a", PrimitiveValType::String),
709
///       ("b", PrimitiveValType::String)
710
///     ]
711
///   )
712
///   .result(PrimitiveValType::String);
713
///
714
/// let mut component = Component::new();
715
/// component.section(&types);
716
///
717
/// let bytes = component.finish();
718
/// ```
719
#[derive(Clone, Debug, Default)]
720
pub struct ComponentTypeSection {
721
    bytes: Vec<u8>,
722
    num_added: u32,
723
}
724
725
impl ComponentTypeSection {
726
    /// Create a new component type section encoder.
727
0
    pub fn new() -> Self {
728
0
        Self::default()
729
0
    }
Unexecuted instantiation: _RNvMse_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_20ComponentTypeSection3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMse_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_20ComponentTypeSection3newB9_
730
731
    /// The number of types in the section.
732
0
    pub fn len(&self) -> u32 {
733
0
        self.num_added
734
0
    }
735
736
    /// Determines if the section is empty.
737
0
    pub fn is_empty(&self) -> bool {
738
0
        self.num_added == 0
739
0
    }
740
741
    /// Encode a type into this section.
742
    ///
743
    /// The returned encoder must be finished before adding another type.
744
    #[must_use = "the encoder must be used to encode the type"]
745
0
    pub fn ty(&mut self) -> ComponentTypeEncoder<'_> {
746
0
        self.num_added += 1;
747
0
        ComponentTypeEncoder(&mut self.bytes)
748
0
    }
749
750
    /// Define a component type in this type section.
751
0
    pub fn component(&mut self, ty: &ComponentType) -> &mut Self {
752
0
        self.ty().component(ty);
753
0
        self
754
0
    }
755
756
    /// Define an instance type in this type section.
757
0
    pub fn instance(&mut self, ty: &InstanceType) -> &mut Self {
758
0
        self.ty().instance(ty);
759
0
        self
760
0
    }
761
762
    /// Define a function type in this type section.
763
0
    pub fn function(&mut self) -> ComponentFuncTypeEncoder<'_> {
764
0
        self.ty().function()
765
0
    }
766
767
    /// Add a component defined type to this type section.
768
    ///
769
    /// The returned encoder must be used before adding another type.
770
    #[must_use = "the encoder must be used to encode the type"]
771
0
    pub fn defined_type(&mut self) -> ComponentDefinedTypeEncoder<'_> {
772
0
        self.ty().defined_type()
773
0
    }
774
775
    /// Defines a new resource type.
776
0
    pub fn resource(&mut self, rep: ValType, dtor: Option<u32>) -> &mut Self {
777
0
        self.ty().resource(rep, dtor);
778
0
        self
779
0
    }
780
}
781
782
impl Encode for ComponentTypeSection {
783
0
    fn encode(&self, sink: &mut Vec<u8>) {
784
0
        encode_section(sink, self.num_added, &self.bytes);
785
0
    }
786
}
787
788
impl ComponentSection for ComponentTypeSection {
789
0
    fn id(&self) -> u8 {
790
0
        ComponentSectionId::Type.into()
791
0
    }
Unexecuted instantiation: _RNvXsg_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_20ComponentTypeSectionNtB7_16ComponentSection2idCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXsg_NtNtCs5Pk8z11FdwQ_12wasm_encoder9component5typesNtB5_20ComponentTypeSectionNtB7_16ComponentSection2idB9_
792
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core.rs
Line
Count
Source (jump to first uncovered line)
1
mod code;
2
mod custom;
3
mod data;
4
mod dump;
5
mod elements;
6
mod exports;
7
mod functions;
8
mod globals;
9
mod imports;
10
mod linking;
11
mod memories;
12
mod names;
13
mod producers;
14
mod start;
15
mod tables;
16
mod tags;
17
mod types;
18
19
pub use code::*;
20
pub use custom::*;
21
pub use data::*;
22
pub use dump::*;
23
pub use elements::*;
24
pub use exports::*;
25
pub use functions::*;
26
pub use globals::*;
27
pub use imports::*;
28
pub use linking::*;
29
pub use memories::*;
30
pub use names::*;
31
pub use producers::*;
32
pub use start::*;
33
pub use tables::*;
34
pub use tags::*;
35
pub use types::*;
36
37
use crate::Encode;
38
39
pub(crate) const CORE_FUNCTION_SORT: u8 = 0x00;
40
pub(crate) const CORE_TABLE_SORT: u8 = 0x01;
41
pub(crate) const CORE_MEMORY_SORT: u8 = 0x02;
42
pub(crate) const CORE_GLOBAL_SORT: u8 = 0x03;
43
pub(crate) const CORE_TAG_SORT: u8 = 0x04;
44
45
/// A WebAssembly module section.
46
///
47
/// Various builders defined in this crate already implement this trait, but you
48
/// can also implement it yourself for your own custom section builders, or use
49
/// `RawSection` to use a bunch of raw bytes as a section.
50
pub trait Section: Encode {
51
    /// Gets the section identifier for this section.
52
    fn id(&self) -> u8;
53
54
    /// Appends this section to the specified destination list of bytes.
55
0
    fn append_to(&self, dst: &mut Vec<u8>) {
56
0
        dst.push(self.id());
57
0
        self.encode(dst);
58
0
    }
Unexecuted instantiation: _RNvYNtNtCs5Pk8z11FdwQ_12wasm_encoder3raw10RawSectionNtNtB6_4core7Section9append_toB6_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4code11CodeSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4data11DataSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4data16DataCountSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dump15CoreDumpSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dump20CoreDumpStackSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dump22CoreDumpModulesSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dump24CoreDumpInstancesSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4tags10TagSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core5names11NameSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core5start12StartSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core5types11TypeSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core6custom13CustomSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core6custom16RawCustomSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core6tables12TableSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core7exports13ExportSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core7globals13GlobalSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core7imports13ImportSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core7linking14LinkingSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core8elements14ElementSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core8memories13MemorySectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core9functions15FunctionSectionNtB6_7Section9append_toB8_
Unexecuted instantiation: _RNvYNtNtNtCs5Pk8z11FdwQ_12wasm_encoder4core9producers16ProducersSectionNtB6_7Section9append_toB8_
59
}
60
61
/// Known section identifiers of WebAssembly modules.
62
#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)]
63
#[repr(u8)]
64
pub enum SectionId {
65
    /// The custom section.
66
    Custom = 0,
67
    /// The type section.
68
    Type = 1,
69
    /// The import section.
70
    Import = 2,
71
    /// The function section.
72
    Function = 3,
73
    /// The table section.
74
    Table = 4,
75
    /// The memory section.
76
    Memory = 5,
77
    /// The global section.
78
    Global = 6,
79
    /// The export section.
80
    Export = 7,
81
    /// The start section.
82
    Start = 8,
83
    /// The element section.
84
    Element = 9,
85
    /// The code section.
86
    Code = 10,
87
    /// The data section.
88
    Data = 11,
89
    /// The data count section.
90
    DataCount = 12,
91
    /// The tag section.
92
    ///
93
    /// This section is supported by the exception handling proposal.
94
    Tag = 13,
95
}
96
97
impl From<SectionId> for u8 {
98
    #[inline]
99
21.4k
    fn from(id: SectionId) -> u8 {
100
21.4k
        id as u8
101
21.4k
    }
_RNvXNtCs5Pk8z11FdwQ_12wasm_encoder4corehINtNtCs1ujR1JRCAmI_4core7convert4FromNtB2_9SectionIdE4fromCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
99
21.4k
    fn from(id: SectionId) -> u8 {
100
21.4k
        id as u8
101
21.4k
    }
Unexecuted instantiation: _RNvXNtCs5Pk8z11FdwQ_12wasm_encoder4corehINtNtCs1ujR1JRCAmI_4core7convert4FromNtB2_9SectionIdE4fromB4_
102
}
103
104
impl Encode for SectionId {
105
0
    fn encode(&self, sink: &mut Vec<u8>) {
106
0
        sink.push(*self as u8);
107
0
    }
108
}
109
110
/// Represents a WebAssembly component that is being encoded.
111
///
112
/// Sections within a WebAssembly module are encoded in a specific order.
113
///
114
/// Modules may also added as a section to a WebAssembly component.
115
#[derive(Clone, Debug)]
116
pub struct Module {
117
    pub(crate) bytes: Vec<u8>,
118
}
119
120
impl Module {
121
    /// The 8-byte header at the beginning of all core wasm modules.
122
    #[rustfmt::skip]
123
    pub const HEADER: [u8; 8] = [
124
        // Magic
125
        0x00, 0x61, 0x73, 0x6D,
126
        // Version
127
        0x01, 0x00, 0x00, 0x00,
128
    ];
129
130
    /// Begin writing a new `Module`.
131
    #[rustfmt::skip]
132
5.67k
    pub fn new() -> Self {
133
5.67k
        Module {
134
5.67k
            bytes: Self::HEADER.to_vec(),
135
5.67k
        }
136
5.67k
    }
137
138
    /// Write a section into this module.
139
    ///
140
    /// It is your responsibility to define the sections in the [proper
141
    /// order](https://webassembly.github.io/spec/core/binary/modules.html#binary-module),
142
    /// and to ensure that each kind of section (other than custom sections) is
143
    /// only defined once. While this is a potential footgun, it also allows you
144
    /// to use this crate to easily construct test cases for bad Wasm module
145
    /// encodings.
146
21.4k
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
21.4k
        self.bytes.push(section.id());
148
21.4k
        section.encode(&mut self.bytes);
149
21.4k
        self
150
21.4k
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_4code11CodeSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
4.09k
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
4.09k
        self.bytes.push(section.id());
148
4.09k
        section.encode(&mut self.bytes);
149
4.09k
        self
150
4.09k
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_4data11DataSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
176
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
176
        self.bytes.push(section.id());
148
176
        section.encode(&mut self.bytes);
149
176
        self
150
176
    }
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_4data16DataCountSectionECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_4tags10TagSectionECs4eJdYXiOSk9_10wasm_smith
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_5start12StartSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
582
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
582
        self.bytes.push(section.id());
148
582
        section.encode(&mut self.bytes);
149
582
        self
150
582
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_5types11TypeSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
4.63k
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
4.63k
        self.bytes.push(section.id());
148
4.63k
        section.encode(&mut self.bytes);
149
4.63k
        self
150
4.63k
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_6tables12TableSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
1.03k
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
1.03k
        self.bytes.push(section.id());
148
1.03k
        section.encode(&mut self.bytes);
149
1.03k
        self
150
1.03k
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_7exports13ExportSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
897
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
897
        self.bytes.push(section.id());
148
897
        section.encode(&mut self.bytes);
149
897
        self
150
897
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_7globals13GlobalSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
1.67k
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
1.67k
        self.bytes.push(section.id());
148
1.67k
        section.encode(&mut self.bytes);
149
1.67k
        self
150
1.67k
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_7imports13ImportSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
2.55k
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
2.55k
        self.bytes.push(section.id());
148
2.55k
        section.encode(&mut self.bytes);
149
2.55k
        self
150
2.55k
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_8elements14ElementSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
252
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
252
        self.bytes.push(section.id());
148
252
        section.encode(&mut self.bytes);
149
252
        self
150
252
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_8memories13MemorySectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
1.41k
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
1.41k
        self.bytes.push(section.id());
148
1.41k
        section.encode(&mut self.bytes);
149
1.41k
        self
150
1.41k
    }
_RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionNtNtB6_9functions15FunctionSectionECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
146
4.09k
    pub fn section(&mut self, section: &impl Section) -> &mut Self {
147
4.09k
        self.bytes.push(section.id());
148
4.09k
        section.encode(&mut self.bytes);
149
4.09k
        self
150
4.09k
    }
Unexecuted instantiation: _RINvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB6_6Module7sectionpEB8_
151
152
    /// Get the encoded Wasm module as a slice.
153
0
    pub fn as_slice(&self) -> &[u8] {
154
0
        &self.bytes
155
0
    }
156
157
    /// Finish writing this Wasm module and extract ownership of the encoded
158
    /// bytes.
159
5.67k
    pub fn finish(self) -> Vec<u8> {
160
5.67k
        self.bytes
161
5.67k
    }
_RNvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB5_6Module6finishCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
159
5.67k
    pub fn finish(self) -> Vec<u8> {
160
5.67k
        self.bytes
161
5.67k
    }
Unexecuted instantiation: _RNvMs0_NtCs5Pk8z11FdwQ_12wasm_encoder4coreNtB5_6Module6finishB7_
162
}
163
164
impl Default for Module {
165
0
    fn default() -> Self {
166
0
        Self::new()
167
0
    }
168
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/code.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, Encode, HeapType, RefType, Section, SectionId, ValType};
2
use std::borrow::Cow;
3
4
/// An encoder for the code section.
5
///
6
/// Code sections are only supported for modules.
7
///
8
/// # Example
9
///
10
/// ```
11
/// use wasm_encoder::{
12
///     CodeSection, Function, FunctionSection, Instruction, Module,
13
///     TypeSection, ValType
14
/// };
15
///
16
/// let mut types = TypeSection::new();
17
/// types.function(vec![], vec![ValType::I32]);
18
///
19
/// let mut functions = FunctionSection::new();
20
/// let type_index = 0;
21
/// functions.function(type_index);
22
///
23
/// let locals = vec![];
24
/// let mut func = Function::new(locals);
25
/// func.instruction(&Instruction::I32Const(42));
26
/// let mut code = CodeSection::new();
27
/// code.function(&func);
28
///
29
/// let mut module = Module::new();
30
/// module
31
///     .section(&types)
32
///     .section(&functions)
33
///     .section(&code);
34
///
35
/// let wasm_bytes = module.finish();
36
/// ```
37
#[derive(Clone, Default, Debug)]
38
pub struct CodeSection {
39
    bytes: Vec<u8>,
40
    num_added: u32,
41
}
42
43
impl CodeSection {
44
    /// Create a new code section encoder.
45
4.09k
    pub fn new() -> Self {
46
4.09k
        Self::default()
47
4.09k
    }
_RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4codeNtB2_11CodeSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
45
4.09k
    pub fn new() -> Self {
46
4.09k
        Self::default()
47
4.09k
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4codeNtB2_11CodeSection3newB6_
48
49
    /// The number of functions in the section.
50
0
    pub fn len(&self) -> u32 {
51
0
        self.num_added
52
0
    }
53
54
    /// The number of bytes already added to this section.
55
    ///
56
    /// This number doesn't include the vector length that precedes the
57
    /// code entries, since it has a variable size that isn't known until all
58
    /// functions are added.
59
0
    pub fn byte_len(&self) -> usize {
60
0
        self.bytes.len()
61
0
    }
62
63
    /// Determines if the section is empty.
64
0
    pub fn is_empty(&self) -> bool {
65
0
        self.num_added == 0
66
0
    }
67
68
    /// Write a function body into this code section.
69
15.8k
    pub fn function(&mut self, func: &Function) -> &mut Self {
70
15.8k
        func.encode(&mut self.bytes);
71
15.8k
        self.num_added += 1;
72
15.8k
        self
73
15.8k
    }
74
75
    /// Add a raw byte slice into this code section as a function body.
76
    ///
77
    /// The length prefix of the function body will be automatically prepended,
78
    /// and should not be included in the raw byte slice.
79
    ///
80
    /// # Example
81
    ///
82
    /// You can use the `raw` method to copy an already-encoded function body
83
    /// into a new code section encoder:
84
    ///
85
    /// ```
86
    /// # use wasmparser::{BinaryReader, WasmFeatures, CodeSectionReader};
87
    /// //                  id, size, # entries, entry
88
    /// let code_section = [10, 6,    1,         4, 0, 65, 0, 11];
89
    ///
90
    /// // Parse the code section.
91
    /// let reader = BinaryReader::new(&code_section, 0, WasmFeatures::all());
92
    /// let reader = CodeSectionReader::new(reader).unwrap();
93
    /// let body = reader.into_iter().next().unwrap().unwrap();
94
    /// let body_range = body.range();
95
    ///
96
    /// // Add the body to a new code section encoder by copying bytes rather
97
    /// // than re-parsing and re-encoding it.
98
    /// let mut encoder = wasm_encoder::CodeSection::new();
99
    /// encoder.raw(&code_section[body_range.start..body_range.end]);
100
    /// ```
101
0
    pub fn raw(&mut self, data: &[u8]) -> &mut Self {
102
0
        data.encode(&mut self.bytes);
103
0
        self.num_added += 1;
104
0
        self
105
0
    }
106
}
107
108
impl Encode for CodeSection {
109
4.09k
    fn encode(&self, sink: &mut Vec<u8>) {
110
4.09k
        encode_section(sink, self.num_added, &self.bytes);
111
4.09k
    }
112
}
113
114
impl Section for CodeSection {
115
4.09k
    fn id(&self) -> u8 {
116
4.09k
        SectionId::Code.into()
117
4.09k
    }
_RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4codeNtB5_11CodeSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
115
4.09k
    fn id(&self) -> u8 {
116
4.09k
        SectionId::Code.into()
117
4.09k
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4codeNtB5_11CodeSectionNtB7_7Section2idB9_
118
}
119
120
/// An encoder for a function body within the code section.
121
///
122
/// # Example
123
///
124
/// ```
125
/// use wasm_encoder::{CodeSection, Function, Instruction};
126
///
127
/// // Define the function body for:
128
/// //
129
/// //     (func (param i32 i32) (result i32)
130
/// //       local.get 0
131
/// //       local.get 1
132
/// //       i32.add)
133
/// let locals = vec![];
134
/// let mut func = Function::new(locals);
135
/// func.instruction(&Instruction::LocalGet(0));
136
/// func.instruction(&Instruction::LocalGet(1));
137
/// func.instruction(&Instruction::I32Add);
138
///
139
/// // Add our function to the code section.
140
/// let mut code = CodeSection::new();
141
/// code.function(&func);
142
/// ```
143
#[derive(Clone, Debug, Eq, PartialEq)]
144
pub struct Function {
145
    bytes: Vec<u8>,
146
}
147
148
impl Function {
149
    /// Create a new function body with the given locals.
150
    ///
151
    /// The argument is an iterator over `(N, Ty)`, which defines
152
    /// that the next `N` locals will be of type `Ty`.
153
    ///
154
    /// For example, a function with locals 0 and 1 of type I32 and
155
    /// local 2 of type F32 would be created as:
156
    ///
157
    /// ```
158
    /// # use wasm_encoder::{Function, ValType};
159
    /// let f = Function::new([(2, ValType::I32), (1, ValType::F32)]);
160
    /// ```
161
    ///
162
    /// For more information about the code section (and function definition) in the WASM binary format
163
    /// see the [WebAssembly spec](https://webassembly.github.io/spec/core/binary/modules.html#binary-func)
164
15.8k
    pub fn new<L>(locals: L) -> Self
165
15.8k
    where
166
15.8k
        L: IntoIterator<Item = (u32, ValType)>,
167
15.8k
        L::IntoIter: ExactSizeIterator,
168
15.8k
    {
169
15.8k
        let locals = locals.into_iter();
170
15.8k
        let mut bytes = vec![];
171
15.8k
        locals.len().encode(&mut bytes);
172
18.9k
        for (count, ty) in locals {
173
3.10k
            count.encode(&mut bytes);
174
3.10k
            ty.encode(&mut bytes);
175
3.10k
        }
176
15.8k
        Function { bytes }
177
15.8k
    }
_RINvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4codeNtB6_8Function3newINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1d_5slice4iter4IterNtNtB8_5types7ValTypeENCNvMNtNtCs4eJdYXiOSk9_10wasm_smith4core6encodeNtB2M_6Module11encode_code0EEB2O_
Line
Count
Source
164
15.8k
    pub fn new<L>(locals: L) -> Self
165
15.8k
    where
166
15.8k
        L: IntoIterator<Item = (u32, ValType)>,
167
15.8k
        L::IntoIter: ExactSizeIterator,
168
15.8k
    {
169
15.8k
        let locals = locals.into_iter();
170
15.8k
        let mut bytes = vec![];
171
15.8k
        locals.len().encode(&mut bytes);
172
18.9k
        for (count, ty) in locals {
173
3.10k
            count.encode(&mut bytes);
174
3.10k
            ty.encode(&mut bytes);
175
3.10k
        }
176
15.8k
        Function { bytes }
177
15.8k
    }
Unexecuted instantiation: _RINvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4codeNtB6_8Function3newpEBa_
178
179
    /// Create a function from a list of locals' types.
180
    ///
181
    /// Unlike [`Function::new`], this constructor simply takes a list of types
182
    /// which are in order associated with locals.
183
    ///
184
    /// For example:
185
    ///
186
    ///  ```
187
    /// # use wasm_encoder::{Function, ValType};
188
    /// let f = Function::new([(2, ValType::I32), (1, ValType::F32)]);
189
    /// let g = Function::new_with_locals_types([
190
    ///     ValType::I32, ValType::I32, ValType::F32
191
    /// ]);
192
    ///
193
    /// assert_eq!(f, g)
194
    /// ```
195
0
    pub fn new_with_locals_types<L>(locals: L) -> Self
196
0
    where
197
0
        L: IntoIterator<Item = ValType>,
198
0
    {
199
0
        let locals = locals.into_iter();
200
0
201
0
        let mut locals_collected: Vec<(u32, ValType)> = vec![];
202
0
        for l in locals {
203
0
            if let Some((last_count, last_type)) = locals_collected.last_mut() {
204
0
                if l == *last_type {
205
                    // Increment the count of consecutive locals of this type
206
0
                    *last_count += 1;
207
0
                    continue;
208
0
                }
209
0
            }
210
            // If we didn't increment, a new type of local appeared
211
0
            locals_collected.push((1, l));
212
        }
213
214
0
        Function::new(locals_collected)
215
0
    }
216
217
    /// Write an instruction into this function body.
218
125k
    pub fn instruction(&mut self, instruction: &Instruction) -> &mut Self {
219
125k
        instruction.encode(&mut self.bytes);
220
125k
        self
221
125k
    }
222
223
    /// Add raw bytes to this function's body.
224
0
    pub fn raw<B>(&mut self, bytes: B) -> &mut Self
225
0
    where
226
0
        B: IntoIterator<Item = u8>,
227
0
    {
228
0
        self.bytes.extend(bytes);
229
0
        self
230
0
    }
Unexecuted instantiation: _RINvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4codeNtB6_8Function3rawINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1d_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4codeNtB6_8Function3rawpEBa_
231
232
    /// The number of bytes already added to this function.
233
    ///
234
    /// This number doesn't include the variable-width size field that `encode`
235
    /// will write before the added bytes, since the size of that field isn't
236
    /// known until all the instructions are added to this function.
237
0
    pub fn byte_len(&self) -> usize {
238
0
        self.bytes.len()
239
0
    }
240
}
241
242
impl Encode for Function {
243
15.8k
    fn encode(&self, sink: &mut Vec<u8>) {
244
15.8k
        self.bytes.encode(sink);
245
15.8k
    }
246
}
247
248
/// The immediate for a memory instruction.
249
#[derive(Clone, Copy, Debug)]
250
pub struct MemArg {
251
    /// A static offset to add to the instruction's dynamic address operand.
252
    ///
253
    /// This is a `u64` field for the memory64 proposal, but 32-bit memories
254
    /// limit offsets to at most `u32::MAX` bytes. This will be encoded as a LEB
255
    /// but it won't generate a valid module if an offset is specified which is
256
    /// larger than the maximum size of the index space for the memory indicated
257
    /// by `memory_index`.
258
    pub offset: u64,
259
    /// The expected alignment of the instruction's dynamic address operand
260
    /// (expressed the exponent of a power of two).
261
    pub align: u32,
262
    /// The index of the memory this instruction is operating upon.
263
    pub memory_index: u32,
264
}
265
266
impl Encode for MemArg {
267
3.66k
    fn encode(&self, sink: &mut Vec<u8>) {
268
3.66k
        if self.memory_index == 0 {
269
3.66k
            self.align.encode(sink);
270
3.66k
            self.offset.encode(sink);
271
3.66k
        } else {
272
0
            (self.align | (1 << 6)).encode(sink);
273
0
            self.memory_index.encode(sink);
274
0
            self.offset.encode(sink);
275
0
        }
276
3.66k
    }
277
}
278
279
/// The memory ordering for atomic instructions.
280
///
281
/// For an in-depth explanation of memory orderings, see the C++ documentation
282
/// for [`memory_order`] or the Rust documentation for [`atomic::Ordering`].
283
///
284
/// [`memory_order`]: https://en.cppreference.com/w/cpp/atomic/memory_order
285
/// [`atomic::Ordering`]: https://doc.rust-lang.org/std/sync/atomic/enum.Ordering.html
286
#[derive(Clone, Copy, Debug)]
287
pub enum Ordering {
288
    /// For a load, it acquires; this orders all operations before the last
289
    /// "releasing" store. For a store, it releases; this orders all operations
290
    /// before it at the next "acquiring" load.
291
    AcqRel,
292
    /// Like `AcqRel` but all threads see all sequentially consistent operations
293
    /// in the same order.
294
    SeqCst,
295
}
296
297
impl Encode for Ordering {
298
0
    fn encode(&self, sink: &mut Vec<u8>) {
299
0
        let flag: u8 = match self {
300
0
            Ordering::SeqCst => 0,
301
0
            Ordering::AcqRel => 1,
302
        };
303
0
        sink.push(flag);
304
0
    }
305
}
306
307
/// Describe an unchecked SIMD lane index.
308
pub type Lane = u8;
309
310
/// The type for a `block`/`if`/`loop`.
311
#[derive(Clone, Copy, Debug)]
312
pub enum BlockType {
313
    /// `[] -> []`
314
    Empty,
315
    /// `[] -> [t]`
316
    Result(ValType),
317
    /// The `n`th function type.
318
    FunctionType(u32),
319
}
320
321
impl Encode for BlockType {
322
6.68k
    fn encode(&self, sink: &mut Vec<u8>) {
323
6.68k
        match *self {
324
3.06k
            Self::Empty => sink.push(0x40),
325
1.66k
            Self::Result(ty) => ty.encode(sink),
326
1.95k
            Self::FunctionType(f) => (f as i64).encode(sink),
327
        }
328
6.68k
    }
329
}
330
331
/// WebAssembly instructions.
332
#[derive(Clone, Debug)]
333
#[non_exhaustive]
334
#[allow(missing_docs, non_camel_case_types)]
335
pub enum Instruction<'a> {
336
    // Control instructions.
337
    Unreachable,
338
    Nop,
339
    Block(BlockType),
340
    Loop(BlockType),
341
    If(BlockType),
342
    Else,
343
    End,
344
    Br(u32),
345
    BrIf(u32),
346
    BrTable(Cow<'a, [u32]>, u32),
347
    BrOnNull(u32),
348
    BrOnNonNull(u32),
349
    Return,
350
    Call(u32),
351
    CallRef(u32),
352
    CallIndirect {
353
        ty: u32,
354
        table: u32,
355
    },
356
    ReturnCallRef(u32),
357
    ReturnCall(u32),
358
    ReturnCallIndirect {
359
        ty: u32,
360
        table: u32,
361
    },
362
    TryTable(BlockType, Cow<'a, [Catch]>),
363
    Throw(u32),
364
    ThrowRef,
365
366
    // Deprecated exception-handling instructions
367
    Try(BlockType),
368
    Delegate(u32),
369
    Catch(u32),
370
    CatchAll,
371
    Rethrow(u32),
372
373
    // Parametric instructions.
374
    Drop,
375
    Select,
376
377
    // Variable instructions.
378
    LocalGet(u32),
379
    LocalSet(u32),
380
    LocalTee(u32),
381
    GlobalGet(u32),
382
    GlobalSet(u32),
383
384
    // Memory instructions.
385
    I32Load(MemArg),
386
    I64Load(MemArg),
387
    F32Load(MemArg),
388
    F64Load(MemArg),
389
    I32Load8S(MemArg),
390
    I32Load8U(MemArg),
391
    I32Load16S(MemArg),
392
    I32Load16U(MemArg),
393
    I64Load8S(MemArg),
394
    I64Load8U(MemArg),
395
    I64Load16S(MemArg),
396
    I64Load16U(MemArg),
397
    I64Load32S(MemArg),
398
    I64Load32U(MemArg),
399
    I32Store(MemArg),
400
    I64Store(MemArg),
401
    F32Store(MemArg),
402
    F64Store(MemArg),
403
    I32Store8(MemArg),
404
    I32Store16(MemArg),
405
    I64Store8(MemArg),
406
    I64Store16(MemArg),
407
    I64Store32(MemArg),
408
    MemorySize(u32),
409
    MemoryGrow(u32),
410
    MemoryInit {
411
        mem: u32,
412
        data_index: u32,
413
    },
414
    DataDrop(u32),
415
    MemoryCopy {
416
        src_mem: u32,
417
        dst_mem: u32,
418
    },
419
    MemoryFill(u32),
420
    MemoryDiscard(u32),
421
422
    // Numeric instructions.
423
    I32Const(i32),
424
    I64Const(i64),
425
    F32Const(f32),
426
    F64Const(f64),
427
    I32Eqz,
428
    I32Eq,
429
    I32Ne,
430
    I32LtS,
431
    I32LtU,
432
    I32GtS,
433
    I32GtU,
434
    I32LeS,
435
    I32LeU,
436
    I32GeS,
437
    I32GeU,
438
    I64Eqz,
439
    I64Eq,
440
    I64Ne,
441
    I64LtS,
442
    I64LtU,
443
    I64GtS,
444
    I64GtU,
445
    I64LeS,
446
    I64LeU,
447
    I64GeS,
448
    I64GeU,
449
    F32Eq,
450
    F32Ne,
451
    F32Lt,
452
    F32Gt,
453
    F32Le,
454
    F32Ge,
455
    F64Eq,
456
    F64Ne,
457
    F64Lt,
458
    F64Gt,
459
    F64Le,
460
    F64Ge,
461
    I32Clz,
462
    I32Ctz,
463
    I32Popcnt,
464
    I32Add,
465
    I32Sub,
466
    I32Mul,
467
    I32DivS,
468
    I32DivU,
469
    I32RemS,
470
    I32RemU,
471
    I32And,
472
    I32Or,
473
    I32Xor,
474
    I32Shl,
475
    I32ShrS,
476
    I32ShrU,
477
    I32Rotl,
478
    I32Rotr,
479
    I64Clz,
480
    I64Ctz,
481
    I64Popcnt,
482
    I64Add,
483
    I64Sub,
484
    I64Mul,
485
    I64DivS,
486
    I64DivU,
487
    I64RemS,
488
    I64RemU,
489
    I64And,
490
    I64Or,
491
    I64Xor,
492
    I64Shl,
493
    I64ShrS,
494
    I64ShrU,
495
    I64Rotl,
496
    I64Rotr,
497
    F32Abs,
498
    F32Neg,
499
    F32Ceil,
500
    F32Floor,
501
    F32Trunc,
502
    F32Nearest,
503
    F32Sqrt,
504
    F32Add,
505
    F32Sub,
506
    F32Mul,
507
    F32Div,
508
    F32Min,
509
    F32Max,
510
    F32Copysign,
511
    F64Abs,
512
    F64Neg,
513
    F64Ceil,
514
    F64Floor,
515
    F64Trunc,
516
    F64Nearest,
517
    F64Sqrt,
518
    F64Add,
519
    F64Sub,
520
    F64Mul,
521
    F64Div,
522
    F64Min,
523
    F64Max,
524
    F64Copysign,
525
    I32WrapI64,
526
    I32TruncF32S,
527
    I32TruncF32U,
528
    I32TruncF64S,
529
    I32TruncF64U,
530
    I64ExtendI32S,
531
    I64ExtendI32U,
532
    I64TruncF32S,
533
    I64TruncF32U,
534
    I64TruncF64S,
535
    I64TruncF64U,
536
    F32ConvertI32S,
537
    F32ConvertI32U,
538
    F32ConvertI64S,
539
    F32ConvertI64U,
540
    F32DemoteF64,
541
    F64ConvertI32S,
542
    F64ConvertI32U,
543
    F64ConvertI64S,
544
    F64ConvertI64U,
545
    F64PromoteF32,
546
    I32ReinterpretF32,
547
    I64ReinterpretF64,
548
    F32ReinterpretI32,
549
    F64ReinterpretI64,
550
    I32Extend8S,
551
    I32Extend16S,
552
    I64Extend8S,
553
    I64Extend16S,
554
    I64Extend32S,
555
    I32TruncSatF32S,
556
    I32TruncSatF32U,
557
    I32TruncSatF64S,
558
    I32TruncSatF64U,
559
    I64TruncSatF32S,
560
    I64TruncSatF32U,
561
    I64TruncSatF64S,
562
    I64TruncSatF64U,
563
564
    // Reference types instructions.
565
    TypedSelect(ValType),
566
    RefNull(HeapType),
567
    RefIsNull,
568
    RefFunc(u32),
569
    RefEq,
570
    RefAsNonNull,
571
572
    // GC types instructions.
573
    StructNew(u32),
574
    StructNewDefault(u32),
575
    StructGet {
576
        struct_type_index: u32,
577
        field_index: u32,
578
    },
579
    StructGetS {
580
        struct_type_index: u32,
581
        field_index: u32,
582
    },
583
    StructGetU {
584
        struct_type_index: u32,
585
        field_index: u32,
586
    },
587
    StructSet {
588
        struct_type_index: u32,
589
        field_index: u32,
590
    },
591
592
    ArrayNew(u32),
593
    ArrayNewDefault(u32),
594
    ArrayNewFixed {
595
        array_type_index: u32,
596
        array_size: u32,
597
    },
598
    ArrayNewData {
599
        array_type_index: u32,
600
        array_data_index: u32,
601
    },
602
    ArrayNewElem {
603
        array_type_index: u32,
604
        array_elem_index: u32,
605
    },
606
    ArrayGet(u32),
607
    ArrayGetS(u32),
608
    ArrayGetU(u32),
609
    ArraySet(u32),
610
    ArrayLen,
611
    ArrayFill(u32),
612
    ArrayCopy {
613
        array_type_index_dst: u32,
614
        array_type_index_src: u32,
615
    },
616
    ArrayInitData {
617
        array_type_index: u32,
618
        array_data_index: u32,
619
    },
620
    ArrayInitElem {
621
        array_type_index: u32,
622
        array_elem_index: u32,
623
    },
624
    RefTestNonNull(HeapType),
625
    RefTestNullable(HeapType),
626
    RefCastNonNull(HeapType),
627
    RefCastNullable(HeapType),
628
    BrOnCast {
629
        relative_depth: u32,
630
        from_ref_type: RefType,
631
        to_ref_type: RefType,
632
    },
633
    BrOnCastFail {
634
        relative_depth: u32,
635
        from_ref_type: RefType,
636
        to_ref_type: RefType,
637
    },
638
    AnyConvertExtern,
639
    ExternConvertAny,
640
641
    RefI31,
642
    I31GetS,
643
    I31GetU,
644
645
    // Bulk memory instructions.
646
    TableInit {
647
        elem_index: u32,
648
        table: u32,
649
    },
650
    ElemDrop(u32),
651
    TableFill(u32),
652
    TableSet(u32),
653
    TableGet(u32),
654
    TableGrow(u32),
655
    TableSize(u32),
656
    TableCopy {
657
        src_table: u32,
658
        dst_table: u32,
659
    },
660
661
    // SIMD instructions.
662
    V128Load(MemArg),
663
    V128Load8x8S(MemArg),
664
    V128Load8x8U(MemArg),
665
    V128Load16x4S(MemArg),
666
    V128Load16x4U(MemArg),
667
    V128Load32x2S(MemArg),
668
    V128Load32x2U(MemArg),
669
    V128Load8Splat(MemArg),
670
    V128Load16Splat(MemArg),
671
    V128Load32Splat(MemArg),
672
    V128Load64Splat(MemArg),
673
    V128Load32Zero(MemArg),
674
    V128Load64Zero(MemArg),
675
    V128Store(MemArg),
676
    V128Load8Lane {
677
        memarg: MemArg,
678
        lane: Lane,
679
    },
680
    V128Load16Lane {
681
        memarg: MemArg,
682
        lane: Lane,
683
    },
684
    V128Load32Lane {
685
        memarg: MemArg,
686
        lane: Lane,
687
    },
688
    V128Load64Lane {
689
        memarg: MemArg,
690
        lane: Lane,
691
    },
692
    V128Store8Lane {
693
        memarg: MemArg,
694
        lane: Lane,
695
    },
696
    V128Store16Lane {
697
        memarg: MemArg,
698
        lane: Lane,
699
    },
700
    V128Store32Lane {
701
        memarg: MemArg,
702
        lane: Lane,
703
    },
704
    V128Store64Lane {
705
        memarg: MemArg,
706
        lane: Lane,
707
    },
708
    V128Const(i128),
709
    I8x16Shuffle([Lane; 16]),
710
    I8x16ExtractLaneS(Lane),
711
    I8x16ExtractLaneU(Lane),
712
    I8x16ReplaceLane(Lane),
713
    I16x8ExtractLaneS(Lane),
714
    I16x8ExtractLaneU(Lane),
715
    I16x8ReplaceLane(Lane),
716
    I32x4ExtractLane(Lane),
717
    I32x4ReplaceLane(Lane),
718
    I64x2ExtractLane(Lane),
719
    I64x2ReplaceLane(Lane),
720
    F32x4ExtractLane(Lane),
721
    F32x4ReplaceLane(Lane),
722
    F64x2ExtractLane(Lane),
723
    F64x2ReplaceLane(Lane),
724
    I8x16Swizzle,
725
    I8x16Splat,
726
    I16x8Splat,
727
    I32x4Splat,
728
    I64x2Splat,
729
    F32x4Splat,
730
    F64x2Splat,
731
    I8x16Eq,
732
    I8x16Ne,
733
    I8x16LtS,
734
    I8x16LtU,
735
    I8x16GtS,
736
    I8x16GtU,
737
    I8x16LeS,
738
    I8x16LeU,
739
    I8x16GeS,
740
    I8x16GeU,
741
    I16x8Eq,
742
    I16x8Ne,
743
    I16x8LtS,
744
    I16x8LtU,
745
    I16x8GtS,
746
    I16x8GtU,
747
    I16x8LeS,
748
    I16x8LeU,
749
    I16x8GeS,
750
    I16x8GeU,
751
    I32x4Eq,
752
    I32x4Ne,
753
    I32x4LtS,
754
    I32x4LtU,
755
    I32x4GtS,
756
    I32x4GtU,
757
    I32x4LeS,
758
    I32x4LeU,
759
    I32x4GeS,
760
    I32x4GeU,
761
    I64x2Eq,
762
    I64x2Ne,
763
    I64x2LtS,
764
    I64x2GtS,
765
    I64x2LeS,
766
    I64x2GeS,
767
    F32x4Eq,
768
    F32x4Ne,
769
    F32x4Lt,
770
    F32x4Gt,
771
    F32x4Le,
772
    F32x4Ge,
773
    F64x2Eq,
774
    F64x2Ne,
775
    F64x2Lt,
776
    F64x2Gt,
777
    F64x2Le,
778
    F64x2Ge,
779
    V128Not,
780
    V128And,
781
    V128AndNot,
782
    V128Or,
783
    V128Xor,
784
    V128Bitselect,
785
    V128AnyTrue,
786
    I8x16Abs,
787
    I8x16Neg,
788
    I8x16Popcnt,
789
    I8x16AllTrue,
790
    I8x16Bitmask,
791
    I8x16NarrowI16x8S,
792
    I8x16NarrowI16x8U,
793
    I8x16Shl,
794
    I8x16ShrS,
795
    I8x16ShrU,
796
    I8x16Add,
797
    I8x16AddSatS,
798
    I8x16AddSatU,
799
    I8x16Sub,
800
    I8x16SubSatS,
801
    I8x16SubSatU,
802
    I8x16MinS,
803
    I8x16MinU,
804
    I8x16MaxS,
805
    I8x16MaxU,
806
    I8x16AvgrU,
807
    I16x8ExtAddPairwiseI8x16S,
808
    I16x8ExtAddPairwiseI8x16U,
809
    I16x8Abs,
810
    I16x8Neg,
811
    I16x8Q15MulrSatS,
812
    I16x8AllTrue,
813
    I16x8Bitmask,
814
    I16x8NarrowI32x4S,
815
    I16x8NarrowI32x4U,
816
    I16x8ExtendLowI8x16S,
817
    I16x8ExtendHighI8x16S,
818
    I16x8ExtendLowI8x16U,
819
    I16x8ExtendHighI8x16U,
820
    I16x8Shl,
821
    I16x8ShrS,
822
    I16x8ShrU,
823
    I16x8Add,
824
    I16x8AddSatS,
825
    I16x8AddSatU,
826
    I16x8Sub,
827
    I16x8SubSatS,
828
    I16x8SubSatU,
829
    I16x8Mul,
830
    I16x8MinS,
831
    I16x8MinU,
832
    I16x8MaxS,
833
    I16x8MaxU,
834
    I16x8AvgrU,
835
    I16x8ExtMulLowI8x16S,
836
    I16x8ExtMulHighI8x16S,
837
    I16x8ExtMulLowI8x16U,
838
    I16x8ExtMulHighI8x16U,
839
    I32x4ExtAddPairwiseI16x8S,
840
    I32x4ExtAddPairwiseI16x8U,
841
    I32x4Abs,
842
    I32x4Neg,
843
    I32x4AllTrue,
844
    I32x4Bitmask,
845
    I32x4ExtendLowI16x8S,
846
    I32x4ExtendHighI16x8S,
847
    I32x4ExtendLowI16x8U,
848
    I32x4ExtendHighI16x8U,
849
    I32x4Shl,
850
    I32x4ShrS,
851
    I32x4ShrU,
852
    I32x4Add,
853
    I32x4Sub,
854
    I32x4Mul,
855
    I32x4MinS,
856
    I32x4MinU,
857
    I32x4MaxS,
858
    I32x4MaxU,
859
    I32x4DotI16x8S,
860
    I32x4ExtMulLowI16x8S,
861
    I32x4ExtMulHighI16x8S,
862
    I32x4ExtMulLowI16x8U,
863
    I32x4ExtMulHighI16x8U,
864
    I64x2Abs,
865
    I64x2Neg,
866
    I64x2AllTrue,
867
    I64x2Bitmask,
868
    I64x2ExtendLowI32x4S,
869
    I64x2ExtendHighI32x4S,
870
    I64x2ExtendLowI32x4U,
871
    I64x2ExtendHighI32x4U,
872
    I64x2Shl,
873
    I64x2ShrS,
874
    I64x2ShrU,
875
    I64x2Add,
876
    I64x2Sub,
877
    I64x2Mul,
878
    I64x2ExtMulLowI32x4S,
879
    I64x2ExtMulHighI32x4S,
880
    I64x2ExtMulLowI32x4U,
881
    I64x2ExtMulHighI32x4U,
882
    F32x4Ceil,
883
    F32x4Floor,
884
    F32x4Trunc,
885
    F32x4Nearest,
886
    F32x4Abs,
887
    F32x4Neg,
888
    F32x4Sqrt,
889
    F32x4Add,
890
    F32x4Sub,
891
    F32x4Mul,
892
    F32x4Div,
893
    F32x4Min,
894
    F32x4Max,
895
    F32x4PMin,
896
    F32x4PMax,
897
    F64x2Ceil,
898
    F64x2Floor,
899
    F64x2Trunc,
900
    F64x2Nearest,
901
    F64x2Abs,
902
    F64x2Neg,
903
    F64x2Sqrt,
904
    F64x2Add,
905
    F64x2Sub,
906
    F64x2Mul,
907
    F64x2Div,
908
    F64x2Min,
909
    F64x2Max,
910
    F64x2PMin,
911
    F64x2PMax,
912
    I32x4TruncSatF32x4S,
913
    I32x4TruncSatF32x4U,
914
    F32x4ConvertI32x4S,
915
    F32x4ConvertI32x4U,
916
    I32x4TruncSatF64x2SZero,
917
    I32x4TruncSatF64x2UZero,
918
    F64x2ConvertLowI32x4S,
919
    F64x2ConvertLowI32x4U,
920
    F32x4DemoteF64x2Zero,
921
    F64x2PromoteLowF32x4,
922
923
    // Relaxed simd proposal
924
    I8x16RelaxedSwizzle,
925
    I32x4RelaxedTruncF32x4S,
926
    I32x4RelaxedTruncF32x4U,
927
    I32x4RelaxedTruncF64x2SZero,
928
    I32x4RelaxedTruncF64x2UZero,
929
    F32x4RelaxedMadd,
930
    F32x4RelaxedNmadd,
931
    F64x2RelaxedMadd,
932
    F64x2RelaxedNmadd,
933
    I8x16RelaxedLaneselect,
934
    I16x8RelaxedLaneselect,
935
    I32x4RelaxedLaneselect,
936
    I64x2RelaxedLaneselect,
937
    F32x4RelaxedMin,
938
    F32x4RelaxedMax,
939
    F64x2RelaxedMin,
940
    F64x2RelaxedMax,
941
    I16x8RelaxedQ15mulrS,
942
    I16x8RelaxedDotI8x16I7x16S,
943
    I32x4RelaxedDotI8x16I7x16AddS,
944
945
    // Atomic instructions (the threads proposal)
946
    MemoryAtomicNotify(MemArg),
947
    MemoryAtomicWait32(MemArg),
948
    MemoryAtomicWait64(MemArg),
949
    AtomicFence,
950
    I32AtomicLoad(MemArg),
951
    I64AtomicLoad(MemArg),
952
    I32AtomicLoad8U(MemArg),
953
    I32AtomicLoad16U(MemArg),
954
    I64AtomicLoad8U(MemArg),
955
    I64AtomicLoad16U(MemArg),
956
    I64AtomicLoad32U(MemArg),
957
    I32AtomicStore(MemArg),
958
    I64AtomicStore(MemArg),
959
    I32AtomicStore8(MemArg),
960
    I32AtomicStore16(MemArg),
961
    I64AtomicStore8(MemArg),
962
    I64AtomicStore16(MemArg),
963
    I64AtomicStore32(MemArg),
964
    I32AtomicRmwAdd(MemArg),
965
    I64AtomicRmwAdd(MemArg),
966
    I32AtomicRmw8AddU(MemArg),
967
    I32AtomicRmw16AddU(MemArg),
968
    I64AtomicRmw8AddU(MemArg),
969
    I64AtomicRmw16AddU(MemArg),
970
    I64AtomicRmw32AddU(MemArg),
971
    I32AtomicRmwSub(MemArg),
972
    I64AtomicRmwSub(MemArg),
973
    I32AtomicRmw8SubU(MemArg),
974
    I32AtomicRmw16SubU(MemArg),
975
    I64AtomicRmw8SubU(MemArg),
976
    I64AtomicRmw16SubU(MemArg),
977
    I64AtomicRmw32SubU(MemArg),
978
    I32AtomicRmwAnd(MemArg),
979
    I64AtomicRmwAnd(MemArg),
980
    I32AtomicRmw8AndU(MemArg),
981
    I32AtomicRmw16AndU(MemArg),
982
    I64AtomicRmw8AndU(MemArg),
983
    I64AtomicRmw16AndU(MemArg),
984
    I64AtomicRmw32AndU(MemArg),
985
    I32AtomicRmwOr(MemArg),
986
    I64AtomicRmwOr(MemArg),
987
    I32AtomicRmw8OrU(MemArg),
988
    I32AtomicRmw16OrU(MemArg),
989
    I64AtomicRmw8OrU(MemArg),
990
    I64AtomicRmw16OrU(MemArg),
991
    I64AtomicRmw32OrU(MemArg),
992
    I32AtomicRmwXor(MemArg),
993
    I64AtomicRmwXor(MemArg),
994
    I32AtomicRmw8XorU(MemArg),
995
    I32AtomicRmw16XorU(MemArg),
996
    I64AtomicRmw8XorU(MemArg),
997
    I64AtomicRmw16XorU(MemArg),
998
    I64AtomicRmw32XorU(MemArg),
999
    I32AtomicRmwXchg(MemArg),
1000
    I64AtomicRmwXchg(MemArg),
1001
    I32AtomicRmw8XchgU(MemArg),
1002
    I32AtomicRmw16XchgU(MemArg),
1003
    I64AtomicRmw8XchgU(MemArg),
1004
    I64AtomicRmw16XchgU(MemArg),
1005
    I64AtomicRmw32XchgU(MemArg),
1006
    I32AtomicRmwCmpxchg(MemArg),
1007
    I64AtomicRmwCmpxchg(MemArg),
1008
    I32AtomicRmw8CmpxchgU(MemArg),
1009
    I32AtomicRmw16CmpxchgU(MemArg),
1010
    I64AtomicRmw8CmpxchgU(MemArg),
1011
    I64AtomicRmw16CmpxchgU(MemArg),
1012
    I64AtomicRmw32CmpxchgU(MemArg),
1013
1014
    // More atomic instructions (the shared-everything-threads proposal)
1015
    GlobalAtomicGet {
1016
        ordering: Ordering,
1017
        global_index: u32,
1018
    },
1019
    GlobalAtomicSet {
1020
        ordering: Ordering,
1021
        global_index: u32,
1022
    },
1023
    GlobalAtomicRmwAdd {
1024
        ordering: Ordering,
1025
        global_index: u32,
1026
    },
1027
    GlobalAtomicRmwSub {
1028
        ordering: Ordering,
1029
        global_index: u32,
1030
    },
1031
    GlobalAtomicRmwAnd {
1032
        ordering: Ordering,
1033
        global_index: u32,
1034
    },
1035
    GlobalAtomicRmwOr {
1036
        ordering: Ordering,
1037
        global_index: u32,
1038
    },
1039
    GlobalAtomicRmwXor {
1040
        ordering: Ordering,
1041
        global_index: u32,
1042
    },
1043
    GlobalAtomicRmwXchg {
1044
        ordering: Ordering,
1045
        global_index: u32,
1046
    },
1047
    GlobalAtomicRmwCmpxchg {
1048
        ordering: Ordering,
1049
        global_index: u32,
1050
    },
1051
}
1052
1053
impl Encode for Instruction<'_> {
1054
137k
    fn encode(&self, sink: &mut Vec<u8>) {
1055
137k
        match *self {
1056
            // Control instructions.
1057
9.90k
            Instruction::Unreachable => sink.push(0x00),
1058
1.70k
            Instruction::Nop => sink.push(0x01),
1059
4.04k
            Instruction::Block(bt) => {
1060
4.04k
                sink.push(0x02);
1061
4.04k
                bt.encode(sink);
1062
4.04k
            }
1063
2.22k
            Instruction::Loop(bt) => {
1064
2.22k
                sink.push(0x03);
1065
2.22k
                bt.encode(sink);
1066
2.22k
            }
1067
411
            Instruction::If(bt) => {
1068
411
                sink.push(0x04);
1069
411
                bt.encode(sink);
1070
411
            }
1071
288
            Instruction::Else => sink.push(0x05),
1072
0
            Instruction::Try(bt) => {
1073
0
                sink.push(0x06);
1074
0
                bt.encode(sink);
1075
0
            }
1076
0
            Instruction::Catch(t) => {
1077
0
                sink.push(0x07);
1078
0
                t.encode(sink);
1079
0
            }
1080
0
            Instruction::Throw(t) => {
1081
0
                sink.push(0x08);
1082
0
                t.encode(sink);
1083
0
            }
1084
0
            Instruction::Rethrow(l) => {
1085
0
                sink.push(0x09);
1086
0
                l.encode(sink);
1087
0
            }
1088
0
            Instruction::ThrowRef => {
1089
0
                sink.push(0x0A);
1090
0
            }
1091
28.3k
            Instruction::End => sink.push(0x0B),
1092
2.53k
            Instruction::Br(l) => {
1093
2.53k
                sink.push(0x0C);
1094
2.53k
                l.encode(sink);
1095
2.53k
            }
1096
556
            Instruction::BrIf(l) => {
1097
556
                sink.push(0x0D);
1098
556
                l.encode(sink);
1099
556
            }
1100
726
            Instruction::BrTable(ref ls, l) => {
1101
726
                sink.push(0x0E);
1102
726
                ls.encode(sink);
1103
726
                l.encode(sink);
1104
726
            }
1105
0
            Instruction::BrOnNull(l) => {
1106
0
                sink.push(0xD5);
1107
0
                l.encode(sink);
1108
0
            }
1109
0
            Instruction::BrOnNonNull(l) => {
1110
0
                sink.push(0xD6);
1111
0
                l.encode(sink);
1112
0
            }
1113
465
            Instruction::Return => sink.push(0x0F),
1114
4.35k
            Instruction::Call(f) => {
1115
4.35k
                sink.push(0x10);
1116
4.35k
                f.encode(sink);
1117
4.35k
            }
1118
0
            Instruction::CallRef(ty) => {
1119
0
                sink.push(0x14);
1120
0
                ty.encode(sink);
1121
0
            }
1122
461
            Instruction::CallIndirect { ty, table } => {
1123
461
                sink.push(0x11);
1124
461
                ty.encode(sink);
1125
461
                table.encode(sink);
1126
461
            }
1127
0
            Instruction::ReturnCallRef(ty) => {
1128
0
                sink.push(0x15);
1129
0
                ty.encode(sink);
1130
0
            }
1131
1132
0
            Instruction::ReturnCall(f) => {
1133
0
                sink.push(0x12);
1134
0
                f.encode(sink);
1135
0
            }
1136
0
            Instruction::ReturnCallIndirect { ty, table } => {
1137
0
                sink.push(0x13);
1138
0
                ty.encode(sink);
1139
0
                table.encode(sink);
1140
0
            }
1141
0
            Instruction::Delegate(l) => {
1142
0
                sink.push(0x18);
1143
0
                l.encode(sink);
1144
0
            }
1145
0
            Instruction::CatchAll => {
1146
0
                sink.push(0x19);
1147
0
            }
1148
1149
            // Parametric instructions.
1150
1.25k
            Instruction::Drop => sink.push(0x1A),
1151
116
            Instruction::Select => sink.push(0x1B),
1152
0
            Instruction::TypedSelect(ty) => {
1153
0
                sink.push(0x1c);
1154
0
                [ty].encode(sink);
1155
0
            }
1156
1157
0
            Instruction::TryTable(ty, ref catches) => {
1158
0
                sink.push(0x1f);
1159
0
                ty.encode(sink);
1160
0
                catches.encode(sink);
1161
0
            }
1162
1163
            // Variable instructions.
1164
2.89k
            Instruction::LocalGet(l) => {
1165
2.89k
                sink.push(0x20);
1166
2.89k
                l.encode(sink);
1167
2.89k
            }
1168
623
            Instruction::LocalSet(l) => {
1169
623
                sink.push(0x21);
1170
623
                l.encode(sink);
1171
623
            }
1172
1.00k
            Instruction::LocalTee(l) => {
1173
1.00k
                sink.push(0x22);
1174
1.00k
                l.encode(sink);
1175
1.00k
            }
1176
5.80k
            Instruction::GlobalGet(g) => {
1177
5.80k
                sink.push(0x23);
1178
5.80k
                g.encode(sink);
1179
5.80k
            }
1180
3.24k
            Instruction::GlobalSet(g) => {
1181
3.24k
                sink.push(0x24);
1182
3.24k
                g.encode(sink);
1183
3.24k
            }
1184
0
            Instruction::TableGet(table) => {
1185
0
                sink.push(0x25);
1186
0
                table.encode(sink);
1187
0
            }
1188
0
            Instruction::TableSet(table) => {
1189
0
                sink.push(0x26);
1190
0
                table.encode(sink);
1191
0
            }
1192
1193
            // Memory instructions.
1194
261
            Instruction::I32Load(m) => {
1195
261
                sink.push(0x28);
1196
261
                m.encode(sink);
1197
261
            }
1198
263
            Instruction::I64Load(m) => {
1199
263
                sink.push(0x29);
1200
263
                m.encode(sink);
1201
263
            }
1202
172
            Instruction::F32Load(m) => {
1203
172
                sink.push(0x2A);
1204
172
                m.encode(sink);
1205
172
            }
1206
114
            Instruction::F64Load(m) => {
1207
114
                sink.push(0x2B);
1208
114
                m.encode(sink);
1209
114
            }
1210
364
            Instruction::I32Load8S(m) => {
1211
364
                sink.push(0x2C);
1212
364
                m.encode(sink);
1213
364
            }
1214
377
            Instruction::I32Load8U(m) => {
1215
377
                sink.push(0x2D);
1216
377
                m.encode(sink);
1217
377
            }
1218
355
            Instruction::I32Load16S(m) => {
1219
355
                sink.push(0x2E);
1220
355
                m.encode(sink);
1221
355
            }
1222
387
            Instruction::I32Load16U(m) => {
1223
387
                sink.push(0x2F);
1224
387
                m.encode(sink);
1225
387
            }
1226
180
            Instruction::I64Load8S(m) => {
1227
180
                sink.push(0x30);
1228
180
                m.encode(sink);
1229
180
            }
1230
263
            Instruction::I64Load8U(m) => {
1231
263
                sink.push(0x31);
1232
263
                m.encode(sink);
1233
263
            }
1234
220
            Instruction::I64Load16S(m) => {
1235
220
                sink.push(0x32);
1236
220
                m.encode(sink);
1237
220
            }
1238
65
            Instruction::I64Load16U(m) => {
1239
65
                sink.push(0x33);
1240
65
                m.encode(sink);
1241
65
            }
1242
142
            Instruction::I64Load32S(m) => {
1243
142
                sink.push(0x34);
1244
142
                m.encode(sink);
1245
142
            }
1246
115
            Instruction::I64Load32U(m) => {
1247
115
                sink.push(0x35);
1248
115
                m.encode(sink);
1249
115
            }
1250
20
            Instruction::I32Store(m) => {
1251
20
                sink.push(0x36);
1252
20
                m.encode(sink);
1253
20
            }
1254
110
            Instruction::I64Store(m) => {
1255
110
                sink.push(0x37);
1256
110
                m.encode(sink);
1257
110
            }
1258
37
            Instruction::F32Store(m) => {
1259
37
                sink.push(0x38);
1260
37
                m.encode(sink);
1261
37
            }
1262
26
            Instruction::F64Store(m) => {
1263
26
                sink.push(0x39);
1264
26
                m.encode(sink);
1265
26
            }
1266
44
            Instruction::I32Store8(m) => {
1267
44
                sink.push(0x3A);
1268
44
                m.encode(sink);
1269
44
            }
1270
16
            Instruction::I32Store16(m) => {
1271
16
                sink.push(0x3B);
1272
16
                m.encode(sink);
1273
16
            }
1274
65
            Instruction::I64Store8(m) => {
1275
65
                sink.push(0x3C);
1276
65
                m.encode(sink);
1277
65
            }
1278
27
            Instruction::I64Store16(m) => {
1279
27
                sink.push(0x3D);
1280
27
                m.encode(sink);
1281
27
            }
1282
45
            Instruction::I64Store32(m) => {
1283
45
                sink.push(0x3E);
1284
45
                m.encode(sink);
1285
45
            }
1286
1.50k
            Instruction::MemorySize(i) => {
1287
1.50k
                sink.push(0x3F);
1288
1.50k
                i.encode(sink);
1289
1.50k
            }
1290
574
            Instruction::MemoryGrow(i) => {
1291
574
                sink.push(0x40);
1292
574
                i.encode(sink);
1293
574
            }
1294
0
            Instruction::MemoryInit { mem, data_index } => {
1295
0
                sink.push(0xfc);
1296
0
                sink.push(0x08);
1297
0
                data_index.encode(sink);
1298
0
                mem.encode(sink);
1299
0
            }
1300
0
            Instruction::DataDrop(data) => {
1301
0
                sink.push(0xfc);
1302
0
                sink.push(0x09);
1303
0
                data.encode(sink);
1304
0
            }
1305
0
            Instruction::MemoryCopy { src_mem, dst_mem } => {
1306
0
                sink.push(0xfc);
1307
0
                sink.push(0x0a);
1308
0
                dst_mem.encode(sink);
1309
0
                src_mem.encode(sink);
1310
0
            }
1311
0
            Instruction::MemoryFill(mem) => {
1312
0
                sink.push(0xfc);
1313
0
                sink.push(0x0b);
1314
0
                mem.encode(sink);
1315
0
            }
1316
0
            Instruction::MemoryDiscard(mem) => {
1317
0
                sink.push(0xfc);
1318
0
                sink.push(0x12);
1319
0
                mem.encode(sink);
1320
0
            }
1321
1322
            // Numeric instructions.
1323
8.04k
            Instruction::I32Const(x) => {
1324
8.04k
                sink.push(0x41);
1325
8.04k
                x.encode(sink);
1326
8.04k
            }
1327
3.49k
            Instruction::I64Const(x) => {
1328
3.49k
                sink.push(0x42);
1329
3.49k
                x.encode(sink);
1330
3.49k
            }
1331
3.24k
            Instruction::F32Const(x) => {
1332
3.24k
                sink.push(0x43);
1333
3.24k
                let x = x.to_bits();
1334
3.24k
                sink.extend(x.to_le_bytes().iter().copied());
1335
3.24k
            }
1336
2.38k
            Instruction::F64Const(x) => {
1337
2.38k
                sink.push(0x44);
1338
2.38k
                let x = x.to_bits();
1339
2.38k
                sink.extend(x.to_le_bytes().iter().copied());
1340
2.38k
            }
1341
679
            Instruction::I32Eqz => sink.push(0x45),
1342
104
            Instruction::I32Eq => sink.push(0x46),
1343
83
            Instruction::I32Ne => sink.push(0x47),
1344
86
            Instruction::I32LtS => sink.push(0x48),
1345
96
            Instruction::I32LtU => sink.push(0x49),
1346
209
            Instruction::I32GtS => sink.push(0x4A),
1347
35
            Instruction::I32GtU => sink.push(0x4B),
1348
83
            Instruction::I32LeS => sink.push(0x4C),
1349
62
            Instruction::I32LeU => sink.push(0x4D),
1350
58
            Instruction::I32GeS => sink.push(0x4E),
1351
57
            Instruction::I32GeU => sink.push(0x4F),
1352
420
            Instruction::I64Eqz => sink.push(0x50),
1353
25
            Instruction::I64Eq => sink.push(0x51),
1354
30
            Instruction::I64Ne => sink.push(0x52),
1355
27
            Instruction::I64LtS => sink.push(0x53),
1356
55
            Instruction::I64LtU => sink.push(0x54),
1357
23
            Instruction::I64GtS => sink.push(0x55),
1358
89
            Instruction::I64GtU => sink.push(0x56),
1359
53
            Instruction::I64LeS => sink.push(0x57),
1360
53
            Instruction::I64LeU => sink.push(0x58),
1361
49
            Instruction::I64GeS => sink.push(0x59),
1362
84
            Instruction::I64GeU => sink.push(0x5A),
1363
22
            Instruction::F32Eq => sink.push(0x5B),
1364
27
            Instruction::F32Ne => sink.push(0x5C),
1365
20
            Instruction::F32Lt => sink.push(0x5D),
1366
17
            Instruction::F32Gt => sink.push(0x5E),
1367
30
            Instruction::F32Le => sink.push(0x5F),
1368
34
            Instruction::F32Ge => sink.push(0x60),
1369
30
            Instruction::F64Eq => sink.push(0x61),
1370
18
            Instruction::F64Ne => sink.push(0x62),
1371
8
            Instruction::F64Lt => sink.push(0x63),
1372
25
            Instruction::F64Gt => sink.push(0x64),
1373
7
            Instruction::F64Le => sink.push(0x65),
1374
19
            Instruction::F64Ge => sink.push(0x66),
1375
745
            Instruction::I32Clz => sink.push(0x67),
1376
686
            Instruction::I32Ctz => sink.push(0x68),
1377
570
            Instruction::I32Popcnt => sink.push(0x69),
1378
50
            Instruction::I32Add => sink.push(0x6A),
1379
132
            Instruction::I32Sub => sink.push(0x6B),
1380
245
            Instruction::I32Mul => sink.push(0x6C),
1381
83
            Instruction::I32DivS => sink.push(0x6D),
1382
150
            Instruction::I32DivU => sink.push(0x6E),
1383
67
            Instruction::I32RemS => sink.push(0x6F),
1384
153
            Instruction::I32RemU => sink.push(0x70),
1385
182
            Instruction::I32And => sink.push(0x71),
1386
427
            Instruction::I32Or => sink.push(0x72),
1387
2.13k
            Instruction::I32Xor => sink.push(0x73),
1388
82
            Instruction::I32Shl => sink.push(0x74),
1389
73
            Instruction::I32ShrS => sink.push(0x75),
1390
78
            Instruction::I32ShrU => sink.push(0x76),
1391
53
            Instruction::I32Rotl => sink.push(0x77),
1392
162
            Instruction::I32Rotr => sink.push(0x78),
1393
556
            Instruction::I64Clz => sink.push(0x79),
1394
443
            Instruction::I64Ctz => sink.push(0x7A),
1395
645
            Instruction::I64Popcnt => sink.push(0x7B),
1396
25
            Instruction::I64Add => sink.push(0x7C),
1397
65
            Instruction::I64Sub => sink.push(0x7D),
1398
59
            Instruction::I64Mul => sink.push(0x7E),
1399
158
            Instruction::I64DivS => sink.push(0x7F),
1400
116
            Instruction::I64DivU => sink.push(0x80),
1401
54
            Instruction::I64RemS => sink.push(0x81),
1402
40
            Instruction::I64RemU => sink.push(0x82),
1403
117
            Instruction::I64And => sink.push(0x83),
1404
43
            Instruction::I64Or => sink.push(0x84),
1405
1.04k
            Instruction::I64Xor => sink.push(0x85),
1406
83
            Instruction::I64Shl => sink.push(0x86),
1407
68
            Instruction::I64ShrS => sink.push(0x87),
1408
30
            Instruction::I64ShrU => sink.push(0x88),
1409
69
            Instruction::I64Rotl => sink.push(0x89),
1410
35
            Instruction::I64Rotr => sink.push(0x8A),
1411
1.09k
            Instruction::F32Abs => sink.push(0x8B),
1412
714
            Instruction::F32Neg => sink.push(0x8C),
1413
471
            Instruction::F32Ceil => sink.push(0x8D),
1414
750
            Instruction::F32Floor => sink.push(0x8E),
1415
482
            Instruction::F32Trunc => sink.push(0x8F),
1416
667
            Instruction::F32Nearest => sink.push(0x90),
1417
1.11k
            Instruction::F32Sqrt => sink.push(0x91),
1418
54
            Instruction::F32Add => sink.push(0x92),
1419
144
            Instruction::F32Sub => sink.push(0x93),
1420
80
            Instruction::F32Mul => sink.push(0x94),
1421
117
            Instruction::F32Div => sink.push(0x95),
1422
45
            Instruction::F32Min => sink.push(0x96),
1423
134
            Instruction::F32Max => sink.push(0x97),
1424
99
            Instruction::F32Copysign => sink.push(0x98),
1425
584
            Instruction::F64Abs => sink.push(0x99),
1426
375
            Instruction::F64Neg => sink.push(0x9A),
1427
636
            Instruction::F64Ceil => sink.push(0x9B),
1428
667
            Instruction::F64Floor => sink.push(0x9C),
1429
475
            Instruction::F64Trunc => sink.push(0x9D),
1430
433
            Instruction::F64Nearest => sink.push(0x9E),
1431
1.58k
            Instruction::F64Sqrt => sink.push(0x9F),
1432
64
            Instruction::F64Add => sink.push(0xA0),
1433
57
            Instruction::F64Sub => sink.push(0xA1),
1434
63
            Instruction::F64Mul => sink.push(0xA2),
1435
38
            Instruction::F64Div => sink.push(0xA3),
1436
43
            Instruction::F64Min => sink.push(0xA4),
1437
59
            Instruction::F64Max => sink.push(0xA5),
1438
103
            Instruction::F64Copysign => sink.push(0xA6),
1439
485
            Instruction::I32WrapI64 => sink.push(0xA7),
1440
516
            Instruction::I32TruncF32S => sink.push(0xA8),
1441
379
            Instruction::I32TruncF32U => sink.push(0xA9),
1442
330
            Instruction::I32TruncF64S => sink.push(0xAA),
1443
488
            Instruction::I32TruncF64U => sink.push(0xAB),
1444
631
            Instruction::I64ExtendI32S => sink.push(0xAC),
1445
547
            Instruction::I64ExtendI32U => sink.push(0xAD),
1446
399
            Instruction::I64TruncF32S => sink.push(0xAE),
1447
124
            Instruction::I64TruncF32U => sink.push(0xAF),
1448
804
            Instruction::I64TruncF64S => sink.push(0xB0),
1449
242
            Instruction::I64TruncF64U => sink.push(0xB1),
1450
515
            Instruction::F32ConvertI32S => sink.push(0xB2),
1451
375
            Instruction::F32ConvertI32U => sink.push(0xB3),
1452
311
            Instruction::F32ConvertI64S => sink.push(0xB4),
1453
615
            Instruction::F32ConvertI64U => sink.push(0xB5),
1454
545
            Instruction::F32DemoteF64 => sink.push(0xB6),
1455
587
            Instruction::F64ConvertI32S => sink.push(0xB7),
1456
479
            Instruction::F64ConvertI32U => sink.push(0xB8),
1457
392
            Instruction::F64ConvertI64S => sink.push(0xB9),
1458
902
            Instruction::F64ConvertI64U => sink.push(0xBA),
1459
611
            Instruction::F64PromoteF32 => sink.push(0xBB),
1460
1.42k
            Instruction::I32ReinterpretF32 => sink.push(0xBC),
1461
543
            Instruction::I64ReinterpretF64 => sink.push(0xBD),
1462
1.08k
            Instruction::F32ReinterpretI32 => sink.push(0xBE),
1463
527
            Instruction::F64ReinterpretI64 => sink.push(0xBF),
1464
720
            Instruction::I32Extend8S => sink.push(0xC0),
1465
429
            Instruction::I32Extend16S => sink.push(0xC1),
1466
550
            Instruction::I64Extend8S => sink.push(0xC2),
1467
678
            Instruction::I64Extend16S => sink.push(0xC3),
1468
699
            Instruction::I64Extend32S => sink.push(0xC4),
1469
1470
569
            Instruction::I32TruncSatF32S => {
1471
569
                sink.push(0xFC);
1472
569
                sink.push(0x00);
1473
569
            }
1474
504
            Instruction::I32TruncSatF32U => {
1475
504
                sink.push(0xFC);
1476
504
                sink.push(0x01);
1477
504
            }
1478
280
            Instruction::I32TruncSatF64S => {
1479
280
                sink.push(0xFC);
1480
280
                sink.push(0x02);
1481
280
            }
1482
558
            Instruction::I32TruncSatF64U => {
1483
558
                sink.push(0xFC);
1484
558
                sink.push(0x03);
1485
558
            }
1486
179
            Instruction::I64TruncSatF32S => {
1487
179
                sink.push(0xFC);
1488
179
                sink.push(0x04);
1489
179
            }
1490
251
            Instruction::I64TruncSatF32U => {
1491
251
                sink.push(0xFC);
1492
251
                sink.push(0x05);
1493
251
            }
1494
173
            Instruction::I64TruncSatF64S => {
1495
173
                sink.push(0xFC);
1496
173
                sink.push(0x06);
1497
173
            }
1498
146
            Instruction::I64TruncSatF64U => {
1499
146
                sink.push(0xFC);
1500
146
                sink.push(0x07);
1501
146
            }
1502
1503
            // Reference types instructions.
1504
0
            Instruction::RefNull(ty) => {
1505
0
                sink.push(0xd0);
1506
0
                ty.encode(sink);
1507
0
            }
1508
0
            Instruction::RefIsNull => sink.push(0xd1),
1509
0
            Instruction::RefFunc(f) => {
1510
0
                sink.push(0xd2);
1511
0
                f.encode(sink);
1512
0
            }
1513
0
            Instruction::RefEq => sink.push(0xd3),
1514
0
            Instruction::RefAsNonNull => sink.push(0xd4),
1515
1516
            // GC instructions.
1517
0
            Instruction::StructNew(type_index) => {
1518
0
                sink.push(0xfb);
1519
0
                sink.push(0x00);
1520
0
                type_index.encode(sink);
1521
0
            }
1522
0
            Instruction::StructNewDefault(type_index) => {
1523
0
                sink.push(0xfb);
1524
0
                sink.push(0x01);
1525
0
                type_index.encode(sink);
1526
0
            }
1527
            Instruction::StructGet {
1528
0
                struct_type_index,
1529
0
                field_index,
1530
0
            } => {
1531
0
                sink.push(0xfb);
1532
0
                sink.push(0x02);
1533
0
                struct_type_index.encode(sink);
1534
0
                field_index.encode(sink);
1535
0
            }
1536
            Instruction::StructGetS {
1537
0
                struct_type_index,
1538
0
                field_index,
1539
0
            } => {
1540
0
                sink.push(0xfb);
1541
0
                sink.push(0x03);
1542
0
                struct_type_index.encode(sink);
1543
0
                field_index.encode(sink);
1544
0
            }
1545
            Instruction::StructGetU {
1546
0
                struct_type_index,
1547
0
                field_index,
1548
0
            } => {
1549
0
                sink.push(0xfb);
1550
0
                sink.push(0x04);
1551
0
                struct_type_index.encode(sink);
1552
0
                field_index.encode(sink);
1553
0
            }
1554
            Instruction::StructSet {
1555
0
                struct_type_index,
1556
0
                field_index,
1557
0
            } => {
1558
0
                sink.push(0xfb);
1559
0
                sink.push(0x05);
1560
0
                struct_type_index.encode(sink);
1561
0
                field_index.encode(sink);
1562
0
            }
1563
0
            Instruction::ArrayNew(type_index) => {
1564
0
                sink.push(0xfb);
1565
0
                sink.push(0x06);
1566
0
                type_index.encode(sink);
1567
0
            }
1568
0
            Instruction::ArrayNewDefault(type_index) => {
1569
0
                sink.push(0xfb);
1570
0
                sink.push(0x07);
1571
0
                type_index.encode(sink);
1572
0
            }
1573
            Instruction::ArrayNewFixed {
1574
0
                array_type_index,
1575
0
                array_size,
1576
0
            } => {
1577
0
                sink.push(0xfb);
1578
0
                sink.push(0x08);
1579
0
                array_type_index.encode(sink);
1580
0
                array_size.encode(sink);
1581
0
            }
1582
            Instruction::ArrayNewData {
1583
0
                array_type_index,
1584
0
                array_data_index,
1585
0
            } => {
1586
0
                sink.push(0xfb);
1587
0
                sink.push(0x09);
1588
0
                array_type_index.encode(sink);
1589
0
                array_data_index.encode(sink);
1590
0
            }
1591
            Instruction::ArrayNewElem {
1592
0
                array_type_index,
1593
0
                array_elem_index,
1594
0
            } => {
1595
0
                sink.push(0xfb);
1596
0
                sink.push(0x0a);
1597
0
                array_type_index.encode(sink);
1598
0
                array_elem_index.encode(sink);
1599
0
            }
1600
0
            Instruction::ArrayGet(type_index) => {
1601
0
                sink.push(0xfb);
1602
0
                sink.push(0x0b);
1603
0
                type_index.encode(sink);
1604
0
            }
1605
0
            Instruction::ArrayGetS(type_index) => {
1606
0
                sink.push(0xfb);
1607
0
                sink.push(0x0c);
1608
0
                type_index.encode(sink);
1609
0
            }
1610
0
            Instruction::ArrayGetU(type_index) => {
1611
0
                sink.push(0xfb);
1612
0
                sink.push(0x0d);
1613
0
                type_index.encode(sink);
1614
0
            }
1615
0
            Instruction::ArraySet(type_index) => {
1616
0
                sink.push(0xfb);
1617
0
                sink.push(0x0e);
1618
0
                type_index.encode(sink);
1619
0
            }
1620
0
            Instruction::ArrayLen => {
1621
0
                sink.push(0xfb);
1622
0
                sink.push(0x0f);
1623
0
            }
1624
0
            Instruction::ArrayFill(type_index) => {
1625
0
                sink.push(0xfb);
1626
0
                sink.push(0x10);
1627
0
                type_index.encode(sink);
1628
0
            }
1629
            Instruction::ArrayCopy {
1630
0
                array_type_index_dst,
1631
0
                array_type_index_src,
1632
0
            } => {
1633
0
                sink.push(0xfb);
1634
0
                sink.push(0x11);
1635
0
                array_type_index_dst.encode(sink);
1636
0
                array_type_index_src.encode(sink);
1637
0
            }
1638
            Instruction::ArrayInitData {
1639
0
                array_type_index,
1640
0
                array_data_index,
1641
0
            } => {
1642
0
                sink.push(0xfb);
1643
0
                sink.push(0x12);
1644
0
                array_type_index.encode(sink);
1645
0
                array_data_index.encode(sink);
1646
0
            }
1647
            Instruction::ArrayInitElem {
1648
0
                array_type_index,
1649
0
                array_elem_index,
1650
0
            } => {
1651
0
                sink.push(0xfb);
1652
0
                sink.push(0x13);
1653
0
                array_type_index.encode(sink);
1654
0
                array_elem_index.encode(sink);
1655
0
            }
1656
0
            Instruction::RefTestNonNull(heap_type) => {
1657
0
                sink.push(0xfb);
1658
0
                sink.push(0x14);
1659
0
                heap_type.encode(sink);
1660
0
            }
1661
0
            Instruction::RefTestNullable(heap_type) => {
1662
0
                sink.push(0xfb);
1663
0
                sink.push(0x15);
1664
0
                heap_type.encode(sink);
1665
0
            }
1666
0
            Instruction::RefCastNonNull(heap_type) => {
1667
0
                sink.push(0xfb);
1668
0
                sink.push(0x16);
1669
0
                heap_type.encode(sink);
1670
0
            }
1671
0
            Instruction::RefCastNullable(heap_type) => {
1672
0
                sink.push(0xfb);
1673
0
                sink.push(0x17);
1674
0
                heap_type.encode(sink);
1675
0
            }
1676
            Instruction::BrOnCast {
1677
0
                relative_depth,
1678
0
                from_ref_type,
1679
0
                to_ref_type,
1680
0
            } => {
1681
0
                sink.push(0xfb);
1682
0
                sink.push(0x18);
1683
0
                let cast_flags =
1684
0
                    (from_ref_type.nullable as u8) | ((to_ref_type.nullable as u8) << 1);
1685
0
                sink.push(cast_flags);
1686
0
                relative_depth.encode(sink);
1687
0
                from_ref_type.heap_type.encode(sink);
1688
0
                to_ref_type.heap_type.encode(sink);
1689
0
            }
1690
            Instruction::BrOnCastFail {
1691
0
                relative_depth,
1692
0
                from_ref_type,
1693
0
                to_ref_type,
1694
0
            } => {
1695
0
                sink.push(0xfb);
1696
0
                sink.push(0x19);
1697
0
                let cast_flags =
1698
0
                    (from_ref_type.nullable as u8) | ((to_ref_type.nullable as u8) << 1);
1699
0
                sink.push(cast_flags);
1700
0
                relative_depth.encode(sink);
1701
0
                from_ref_type.heap_type.encode(sink);
1702
0
                to_ref_type.heap_type.encode(sink);
1703
0
            }
1704
0
            Instruction::AnyConvertExtern => {
1705
0
                sink.push(0xfb);
1706
0
                sink.push(0x1a);
1707
0
            }
1708
0
            Instruction::ExternConvertAny => {
1709
0
                sink.push(0xfb);
1710
0
                sink.push(0x1b);
1711
0
            }
1712
0
            Instruction::RefI31 => {
1713
0
                sink.push(0xfb);
1714
0
                sink.push(0x1c);
1715
0
            }
1716
0
            Instruction::I31GetS => {
1717
0
                sink.push(0xfb);
1718
0
                sink.push(0x1d);
1719
0
            }
1720
0
            Instruction::I31GetU => {
1721
0
                sink.push(0xfb);
1722
0
                sink.push(0x1e);
1723
0
            }
1724
1725
            // Bulk memory instructions.
1726
0
            Instruction::TableInit { elem_index, table } => {
1727
0
                sink.push(0xfc);
1728
0
                sink.push(0x0c);
1729
0
                elem_index.encode(sink);
1730
0
                table.encode(sink);
1731
0
            }
1732
0
            Instruction::ElemDrop(segment) => {
1733
0
                sink.push(0xfc);
1734
0
                sink.push(0x0d);
1735
0
                segment.encode(sink);
1736
0
            }
1737
            Instruction::TableCopy {
1738
0
                src_table,
1739
0
                dst_table,
1740
0
            } => {
1741
0
                sink.push(0xfc);
1742
0
                sink.push(0x0e);
1743
0
                dst_table.encode(sink);
1744
0
                src_table.encode(sink);
1745
0
            }
1746
0
            Instruction::TableGrow(table) => {
1747
0
                sink.push(0xfc);
1748
0
                sink.push(0x0f);
1749
0
                table.encode(sink);
1750
0
            }
1751
0
            Instruction::TableSize(table) => {
1752
0
                sink.push(0xfc);
1753
0
                sink.push(0x10);
1754
0
                table.encode(sink);
1755
0
            }
1756
0
            Instruction::TableFill(table) => {
1757
0
                sink.push(0xfc);
1758
0
                sink.push(0x11);
1759
0
                table.encode(sink);
1760
0
            }
1761
1762
            // SIMD instructions.
1763
0
            Instruction::V128Load(memarg) => {
1764
0
                sink.push(0xFD);
1765
0
                0x00u32.encode(sink);
1766
0
                memarg.encode(sink);
1767
0
            }
1768
0
            Instruction::V128Load8x8S(memarg) => {
1769
0
                sink.push(0xFD);
1770
0
                0x01u32.encode(sink);
1771
0
                memarg.encode(sink);
1772
0
            }
1773
0
            Instruction::V128Load8x8U(memarg) => {
1774
0
                sink.push(0xFD);
1775
0
                0x02u32.encode(sink);
1776
0
                memarg.encode(sink);
1777
0
            }
1778
0
            Instruction::V128Load16x4S(memarg) => {
1779
0
                sink.push(0xFD);
1780
0
                0x03u32.encode(sink);
1781
0
                memarg.encode(sink);
1782
0
            }
1783
0
            Instruction::V128Load16x4U(memarg) => {
1784
0
                sink.push(0xFD);
1785
0
                0x04u32.encode(sink);
1786
0
                memarg.encode(sink);
1787
0
            }
1788
0
            Instruction::V128Load32x2S(memarg) => {
1789
0
                sink.push(0xFD);
1790
0
                0x05u32.encode(sink);
1791
0
                memarg.encode(sink);
1792
0
            }
1793
0
            Instruction::V128Load32x2U(memarg) => {
1794
0
                sink.push(0xFD);
1795
0
                0x06u32.encode(sink);
1796
0
                memarg.encode(sink);
1797
0
            }
1798
0
            Instruction::V128Load8Splat(memarg) => {
1799
0
                sink.push(0xFD);
1800
0
                0x07u32.encode(sink);
1801
0
                memarg.encode(sink);
1802
0
            }
1803
0
            Instruction::V128Load16Splat(memarg) => {
1804
0
                sink.push(0xFD);
1805
0
                0x08u32.encode(sink);
1806
0
                memarg.encode(sink);
1807
0
            }
1808
0
            Instruction::V128Load32Splat(memarg) => {
1809
0
                sink.push(0xFD);
1810
0
                0x09u32.encode(sink);
1811
0
                memarg.encode(sink);
1812
0
            }
1813
0
            Instruction::V128Load64Splat(memarg) => {
1814
0
                sink.push(0xFD);
1815
0
                0x0Au32.encode(sink);
1816
0
                memarg.encode(sink);
1817
0
            }
1818
0
            Instruction::V128Store(memarg) => {
1819
0
                sink.push(0xFD);
1820
0
                0x0Bu32.encode(sink);
1821
0
                memarg.encode(sink);
1822
0
            }
1823
0
            Instruction::V128Const(x) => {
1824
0
                sink.push(0xFD);
1825
0
                0x0Cu32.encode(sink);
1826
0
                sink.extend(x.to_le_bytes().iter().copied());
1827
0
            }
1828
0
            Instruction::I8x16Shuffle(lanes) => {
1829
0
                sink.push(0xFD);
1830
0
                0x0Du32.encode(sink);
1831
0
                assert!(lanes.iter().all(|l: &u8| *l < 32));
1832
0
                sink.extend(lanes.iter().copied());
1833
            }
1834
0
            Instruction::I8x16Swizzle => {
1835
0
                sink.push(0xFD);
1836
0
                0x0Eu32.encode(sink);
1837
0
            }
1838
0
            Instruction::I8x16Splat => {
1839
0
                sink.push(0xFD);
1840
0
                0x0Fu32.encode(sink);
1841
0
            }
1842
0
            Instruction::I16x8Splat => {
1843
0
                sink.push(0xFD);
1844
0
                0x10u32.encode(sink);
1845
0
            }
1846
0
            Instruction::I32x4Splat => {
1847
0
                sink.push(0xFD);
1848
0
                0x11u32.encode(sink);
1849
0
            }
1850
0
            Instruction::I64x2Splat => {
1851
0
                sink.push(0xFD);
1852
0
                0x12u32.encode(sink);
1853
0
            }
1854
0
            Instruction::F32x4Splat => {
1855
0
                sink.push(0xFD);
1856
0
                0x13u32.encode(sink);
1857
0
            }
1858
0
            Instruction::F64x2Splat => {
1859
0
                sink.push(0xFD);
1860
0
                0x14u32.encode(sink);
1861
0
            }
1862
0
            Instruction::I8x16ExtractLaneS(lane) => {
1863
0
                sink.push(0xFD);
1864
0
                0x15u32.encode(sink);
1865
0
                assert!(lane < 16);
1866
0
                sink.push(lane);
1867
            }
1868
0
            Instruction::I8x16ExtractLaneU(lane) => {
1869
0
                sink.push(0xFD);
1870
0
                0x16u32.encode(sink);
1871
0
                assert!(lane < 16);
1872
0
                sink.push(lane);
1873
            }
1874
0
            Instruction::I8x16ReplaceLane(lane) => {
1875
0
                sink.push(0xFD);
1876
0
                0x17u32.encode(sink);
1877
0
                assert!(lane < 16);
1878
0
                sink.push(lane);
1879
            }
1880
0
            Instruction::I16x8ExtractLaneS(lane) => {
1881
0
                sink.push(0xFD);
1882
0
                0x18u32.encode(sink);
1883
0
                assert!(lane < 8);
1884
0
                sink.push(lane);
1885
            }
1886
0
            Instruction::I16x8ExtractLaneU(lane) => {
1887
0
                sink.push(0xFD);
1888
0
                0x19u32.encode(sink);
1889
0
                assert!(lane < 8);
1890
0
                sink.push(lane);
1891
            }
1892
0
            Instruction::I16x8ReplaceLane(lane) => {
1893
0
                sink.push(0xFD);
1894
0
                0x1Au32.encode(sink);
1895
0
                assert!(lane < 8);
1896
0
                sink.push(lane);
1897
            }
1898
0
            Instruction::I32x4ExtractLane(lane) => {
1899
0
                sink.push(0xFD);
1900
0
                0x1Bu32.encode(sink);
1901
0
                assert!(lane < 4);
1902
0
                sink.push(lane);
1903
            }
1904
0
            Instruction::I32x4ReplaceLane(lane) => {
1905
0
                sink.push(0xFD);
1906
0
                0x1Cu32.encode(sink);
1907
0
                assert!(lane < 4);
1908
0
                sink.push(lane);
1909
            }
1910
0
            Instruction::I64x2ExtractLane(lane) => {
1911
0
                sink.push(0xFD);
1912
0
                0x1Du32.encode(sink);
1913
0
                assert!(lane < 2);
1914
0
                sink.push(lane);
1915
            }
1916
0
            Instruction::I64x2ReplaceLane(lane) => {
1917
0
                sink.push(0xFD);
1918
0
                0x1Eu32.encode(sink);
1919
0
                assert!(lane < 2);
1920
0
                sink.push(lane);
1921
            }
1922
0
            Instruction::F32x4ExtractLane(lane) => {
1923
0
                sink.push(0xFD);
1924
0
                0x1Fu32.encode(sink);
1925
0
                assert!(lane < 4);
1926
0
                sink.push(lane);
1927
            }
1928
0
            Instruction::F32x4ReplaceLane(lane) => {
1929
0
                sink.push(0xFD);
1930
0
                0x20u32.encode(sink);
1931
0
                assert!(lane < 4);
1932
0
                sink.push(lane);
1933
            }
1934
0
            Instruction::F64x2ExtractLane(lane) => {
1935
0
                sink.push(0xFD);
1936
0
                0x21u32.encode(sink);
1937
0
                assert!(lane < 2);
1938
0
                sink.push(lane);
1939
            }
1940
0
            Instruction::F64x2ReplaceLane(lane) => {
1941
0
                sink.push(0xFD);
1942
0
                0x22u32.encode(sink);
1943
0
                assert!(lane < 2);
1944
0
                sink.push(lane);
1945
            }
1946
1947
0
            Instruction::I8x16Eq => {
1948
0
                sink.push(0xFD);
1949
0
                0x23u32.encode(sink);
1950
0
            }
1951
0
            Instruction::I8x16Ne => {
1952
0
                sink.push(0xFD);
1953
0
                0x24u32.encode(sink);
1954
0
            }
1955
0
            Instruction::I8x16LtS => {
1956
0
                sink.push(0xFD);
1957
0
                0x25u32.encode(sink);
1958
0
            }
1959
0
            Instruction::I8x16LtU => {
1960
0
                sink.push(0xFD);
1961
0
                0x26u32.encode(sink);
1962
0
            }
1963
0
            Instruction::I8x16GtS => {
1964
0
                sink.push(0xFD);
1965
0
                0x27u32.encode(sink);
1966
0
            }
1967
0
            Instruction::I8x16GtU => {
1968
0
                sink.push(0xFD);
1969
0
                0x28u32.encode(sink);
1970
0
            }
1971
0
            Instruction::I8x16LeS => {
1972
0
                sink.push(0xFD);
1973
0
                0x29u32.encode(sink);
1974
0
            }
1975
0
            Instruction::I8x16LeU => {
1976
0
                sink.push(0xFD);
1977
0
                0x2Au32.encode(sink);
1978
0
            }
1979
0
            Instruction::I8x16GeS => {
1980
0
                sink.push(0xFD);
1981
0
                0x2Bu32.encode(sink);
1982
0
            }
1983
0
            Instruction::I8x16GeU => {
1984
0
                sink.push(0xFD);
1985
0
                0x2Cu32.encode(sink);
1986
0
            }
1987
0
            Instruction::I16x8Eq => {
1988
0
                sink.push(0xFD);
1989
0
                0x2Du32.encode(sink);
1990
0
            }
1991
0
            Instruction::I16x8Ne => {
1992
0
                sink.push(0xFD);
1993
0
                0x2Eu32.encode(sink);
1994
0
            }
1995
0
            Instruction::I16x8LtS => {
1996
0
                sink.push(0xFD);
1997
0
                0x2Fu32.encode(sink);
1998
0
            }
1999
0
            Instruction::I16x8LtU => {
2000
0
                sink.push(0xFD);
2001
0
                0x30u32.encode(sink);
2002
0
            }
2003
0
            Instruction::I16x8GtS => {
2004
0
                sink.push(0xFD);
2005
0
                0x31u32.encode(sink);
2006
0
            }
2007
0
            Instruction::I16x8GtU => {
2008
0
                sink.push(0xFD);
2009
0
                0x32u32.encode(sink);
2010
0
            }
2011
0
            Instruction::I16x8LeS => {
2012
0
                sink.push(0xFD);
2013
0
                0x33u32.encode(sink);
2014
0
            }
2015
0
            Instruction::I16x8LeU => {
2016
0
                sink.push(0xFD);
2017
0
                0x34u32.encode(sink);
2018
0
            }
2019
0
            Instruction::I16x8GeS => {
2020
0
                sink.push(0xFD);
2021
0
                0x35u32.encode(sink);
2022
0
            }
2023
0
            Instruction::I16x8GeU => {
2024
0
                sink.push(0xFD);
2025
0
                0x36u32.encode(sink);
2026
0
            }
2027
0
            Instruction::I32x4Eq => {
2028
0
                sink.push(0xFD);
2029
0
                0x37u32.encode(sink);
2030
0
            }
2031
0
            Instruction::I32x4Ne => {
2032
0
                sink.push(0xFD);
2033
0
                0x38u32.encode(sink);
2034
0
            }
2035
0
            Instruction::I32x4LtS => {
2036
0
                sink.push(0xFD);
2037
0
                0x39u32.encode(sink);
2038
0
            }
2039
0
            Instruction::I32x4LtU => {
2040
0
                sink.push(0xFD);
2041
0
                0x3Au32.encode(sink);
2042
0
            }
2043
0
            Instruction::I32x4GtS => {
2044
0
                sink.push(0xFD);
2045
0
                0x3Bu32.encode(sink);
2046
0
            }
2047
0
            Instruction::I32x4GtU => {
2048
0
                sink.push(0xFD);
2049
0
                0x3Cu32.encode(sink);
2050
0
            }
2051
0
            Instruction::I32x4LeS => {
2052
0
                sink.push(0xFD);
2053
0
                0x3Du32.encode(sink);
2054
0
            }
2055
0
            Instruction::I32x4LeU => {
2056
0
                sink.push(0xFD);
2057
0
                0x3Eu32.encode(sink);
2058
0
            }
2059
0
            Instruction::I32x4GeS => {
2060
0
                sink.push(0xFD);
2061
0
                0x3Fu32.encode(sink);
2062
0
            }
2063
0
            Instruction::I32x4GeU => {
2064
0
                sink.push(0xFD);
2065
0
                0x40u32.encode(sink);
2066
0
            }
2067
0
            Instruction::F32x4Eq => {
2068
0
                sink.push(0xFD);
2069
0
                0x41u32.encode(sink);
2070
0
            }
2071
0
            Instruction::F32x4Ne => {
2072
0
                sink.push(0xFD);
2073
0
                0x42u32.encode(sink);
2074
0
            }
2075
0
            Instruction::F32x4Lt => {
2076
0
                sink.push(0xFD);
2077
0
                0x43u32.encode(sink);
2078
0
            }
2079
0
            Instruction::F32x4Gt => {
2080
0
                sink.push(0xFD);
2081
0
                0x44u32.encode(sink);
2082
0
            }
2083
0
            Instruction::F32x4Le => {
2084
0
                sink.push(0xFD);
2085
0
                0x45u32.encode(sink);
2086
0
            }
2087
0
            Instruction::F32x4Ge => {
2088
0
                sink.push(0xFD);
2089
0
                0x46u32.encode(sink);
2090
0
            }
2091
0
            Instruction::F64x2Eq => {
2092
0
                sink.push(0xFD);
2093
0
                0x47u32.encode(sink);
2094
0
            }
2095
0
            Instruction::F64x2Ne => {
2096
0
                sink.push(0xFD);
2097
0
                0x48u32.encode(sink);
2098
0
            }
2099
0
            Instruction::F64x2Lt => {
2100
0
                sink.push(0xFD);
2101
0
                0x49u32.encode(sink);
2102
0
            }
2103
0
            Instruction::F64x2Gt => {
2104
0
                sink.push(0xFD);
2105
0
                0x4Au32.encode(sink);
2106
0
            }
2107
0
            Instruction::F64x2Le => {
2108
0
                sink.push(0xFD);
2109
0
                0x4Bu32.encode(sink);
2110
0
            }
2111
0
            Instruction::F64x2Ge => {
2112
0
                sink.push(0xFD);
2113
0
                0x4Cu32.encode(sink);
2114
0
            }
2115
0
            Instruction::V128Not => {
2116
0
                sink.push(0xFD);
2117
0
                0x4Du32.encode(sink);
2118
0
            }
2119
0
            Instruction::V128And => {
2120
0
                sink.push(0xFD);
2121
0
                0x4Eu32.encode(sink);
2122
0
            }
2123
0
            Instruction::V128AndNot => {
2124
0
                sink.push(0xFD);
2125
0
                0x4Fu32.encode(sink);
2126
0
            }
2127
0
            Instruction::V128Or => {
2128
0
                sink.push(0xFD);
2129
0
                0x50u32.encode(sink);
2130
0
            }
2131
0
            Instruction::V128Xor => {
2132
0
                sink.push(0xFD);
2133
0
                0x51u32.encode(sink);
2134
0
            }
2135
0
            Instruction::V128Bitselect => {
2136
0
                sink.push(0xFD);
2137
0
                0x52u32.encode(sink);
2138
0
            }
2139
0
            Instruction::V128AnyTrue => {
2140
0
                sink.push(0xFD);
2141
0
                0x53u32.encode(sink);
2142
0
            }
2143
0
            Instruction::I8x16Abs => {
2144
0
                sink.push(0xFD);
2145
0
                0x60u32.encode(sink);
2146
0
            }
2147
0
            Instruction::I8x16Neg => {
2148
0
                sink.push(0xFD);
2149
0
                0x61u32.encode(sink);
2150
0
            }
2151
0
            Instruction::I8x16Popcnt => {
2152
0
                sink.push(0xFD);
2153
0
                0x62u32.encode(sink);
2154
0
            }
2155
0
            Instruction::I8x16AllTrue => {
2156
0
                sink.push(0xFD);
2157
0
                0x63u32.encode(sink);
2158
0
            }
2159
0
            Instruction::I8x16Bitmask => {
2160
0
                sink.push(0xFD);
2161
0
                0x64u32.encode(sink);
2162
0
            }
2163
0
            Instruction::I8x16NarrowI16x8S => {
2164
0
                sink.push(0xFD);
2165
0
                0x65u32.encode(sink);
2166
0
            }
2167
0
            Instruction::I8x16NarrowI16x8U => {
2168
0
                sink.push(0xFD);
2169
0
                0x66u32.encode(sink);
2170
0
            }
2171
0
            Instruction::I8x16Shl => {
2172
0
                sink.push(0xFD);
2173
0
                0x6bu32.encode(sink);
2174
0
            }
2175
0
            Instruction::I8x16ShrS => {
2176
0
                sink.push(0xFD);
2177
0
                0x6cu32.encode(sink);
2178
0
            }
2179
0
            Instruction::I8x16ShrU => {
2180
0
                sink.push(0xFD);
2181
0
                0x6du32.encode(sink);
2182
0
            }
2183
0
            Instruction::I8x16Add => {
2184
0
                sink.push(0xFD);
2185
0
                0x6eu32.encode(sink);
2186
0
            }
2187
0
            Instruction::I8x16AddSatS => {
2188
0
                sink.push(0xFD);
2189
0
                0x6fu32.encode(sink);
2190
0
            }
2191
0
            Instruction::I8x16AddSatU => {
2192
0
                sink.push(0xFD);
2193
0
                0x70u32.encode(sink);
2194
0
            }
2195
0
            Instruction::I8x16Sub => {
2196
0
                sink.push(0xFD);
2197
0
                0x71u32.encode(sink);
2198
0
            }
2199
0
            Instruction::I8x16SubSatS => {
2200
0
                sink.push(0xFD);
2201
0
                0x72u32.encode(sink);
2202
0
            }
2203
0
            Instruction::I8x16SubSatU => {
2204
0
                sink.push(0xFD);
2205
0
                0x73u32.encode(sink);
2206
0
            }
2207
0
            Instruction::I8x16MinS => {
2208
0
                sink.push(0xFD);
2209
0
                0x76u32.encode(sink);
2210
0
            }
2211
0
            Instruction::I8x16MinU => {
2212
0
                sink.push(0xFD);
2213
0
                0x77u32.encode(sink);
2214
0
            }
2215
0
            Instruction::I8x16MaxS => {
2216
0
                sink.push(0xFD);
2217
0
                0x78u32.encode(sink);
2218
0
            }
2219
0
            Instruction::I8x16MaxU => {
2220
0
                sink.push(0xFD);
2221
0
                0x79u32.encode(sink);
2222
0
            }
2223
0
            Instruction::I8x16AvgrU => {
2224
0
                sink.push(0xFD);
2225
0
                0x7Bu32.encode(sink);
2226
0
            }
2227
0
            Instruction::I16x8ExtAddPairwiseI8x16S => {
2228
0
                sink.push(0xFD);
2229
0
                0x7Cu32.encode(sink);
2230
0
            }
2231
0
            Instruction::I16x8ExtAddPairwiseI8x16U => {
2232
0
                sink.push(0xFD);
2233
0
                0x7Du32.encode(sink);
2234
0
            }
2235
0
            Instruction::I32x4ExtAddPairwiseI16x8S => {
2236
0
                sink.push(0xFD);
2237
0
                0x7Eu32.encode(sink);
2238
0
            }
2239
0
            Instruction::I32x4ExtAddPairwiseI16x8U => {
2240
0
                sink.push(0xFD);
2241
0
                0x7Fu32.encode(sink);
2242
0
            }
2243
0
            Instruction::I16x8Abs => {
2244
0
                sink.push(0xFD);
2245
0
                0x80u32.encode(sink);
2246
0
            }
2247
0
            Instruction::I16x8Neg => {
2248
0
                sink.push(0xFD);
2249
0
                0x81u32.encode(sink);
2250
0
            }
2251
0
            Instruction::I16x8Q15MulrSatS => {
2252
0
                sink.push(0xFD);
2253
0
                0x82u32.encode(sink);
2254
0
            }
2255
0
            Instruction::I16x8AllTrue => {
2256
0
                sink.push(0xFD);
2257
0
                0x83u32.encode(sink);
2258
0
            }
2259
0
            Instruction::I16x8Bitmask => {
2260
0
                sink.push(0xFD);
2261
0
                0x84u32.encode(sink);
2262
0
            }
2263
0
            Instruction::I16x8NarrowI32x4S => {
2264
0
                sink.push(0xFD);
2265
0
                0x85u32.encode(sink);
2266
0
            }
2267
0
            Instruction::I16x8NarrowI32x4U => {
2268
0
                sink.push(0xFD);
2269
0
                0x86u32.encode(sink);
2270
0
            }
2271
0
            Instruction::I16x8ExtendLowI8x16S => {
2272
0
                sink.push(0xFD);
2273
0
                0x87u32.encode(sink);
2274
0
            }
2275
0
            Instruction::I16x8ExtendHighI8x16S => {
2276
0
                sink.push(0xFD);
2277
0
                0x88u32.encode(sink);
2278
0
            }
2279
0
            Instruction::I16x8ExtendLowI8x16U => {
2280
0
                sink.push(0xFD);
2281
0
                0x89u32.encode(sink);
2282
0
            }
2283
0
            Instruction::I16x8ExtendHighI8x16U => {
2284
0
                sink.push(0xFD);
2285
0
                0x8Au32.encode(sink);
2286
0
            }
2287
0
            Instruction::I16x8Shl => {
2288
0
                sink.push(0xFD);
2289
0
                0x8Bu32.encode(sink);
2290
0
            }
2291
0
            Instruction::I16x8ShrS => {
2292
0
                sink.push(0xFD);
2293
0
                0x8Cu32.encode(sink);
2294
0
            }
2295
0
            Instruction::I16x8ShrU => {
2296
0
                sink.push(0xFD);
2297
0
                0x8Du32.encode(sink);
2298
0
            }
2299
0
            Instruction::I16x8Add => {
2300
0
                sink.push(0xFD);
2301
0
                0x8Eu32.encode(sink);
2302
0
            }
2303
0
            Instruction::I16x8AddSatS => {
2304
0
                sink.push(0xFD);
2305
0
                0x8Fu32.encode(sink);
2306
0
            }
2307
0
            Instruction::I16x8AddSatU => {
2308
0
                sink.push(0xFD);
2309
0
                0x90u32.encode(sink);
2310
0
            }
2311
0
            Instruction::I16x8Sub => {
2312
0
                sink.push(0xFD);
2313
0
                0x91u32.encode(sink);
2314
0
            }
2315
0
            Instruction::I16x8SubSatS => {
2316
0
                sink.push(0xFD);
2317
0
                0x92u32.encode(sink);
2318
0
            }
2319
0
            Instruction::I16x8SubSatU => {
2320
0
                sink.push(0xFD);
2321
0
                0x93u32.encode(sink);
2322
0
            }
2323
0
            Instruction::I16x8Mul => {
2324
0
                sink.push(0xFD);
2325
0
                0x95u32.encode(sink);
2326
0
            }
2327
0
            Instruction::I16x8MinS => {
2328
0
                sink.push(0xFD);
2329
0
                0x96u32.encode(sink);
2330
0
            }
2331
0
            Instruction::I16x8MinU => {
2332
0
                sink.push(0xFD);
2333
0
                0x97u32.encode(sink);
2334
0
            }
2335
0
            Instruction::I16x8MaxS => {
2336
0
                sink.push(0xFD);
2337
0
                0x98u32.encode(sink);
2338
0
            }
2339
0
            Instruction::I16x8MaxU => {
2340
0
                sink.push(0xFD);
2341
0
                0x99u32.encode(sink);
2342
0
            }
2343
0
            Instruction::I16x8AvgrU => {
2344
0
                sink.push(0xFD);
2345
0
                0x9Bu32.encode(sink);
2346
0
            }
2347
0
            Instruction::I16x8ExtMulLowI8x16S => {
2348
0
                sink.push(0xFD);
2349
0
                0x9Cu32.encode(sink);
2350
0
            }
2351
0
            Instruction::I16x8ExtMulHighI8x16S => {
2352
0
                sink.push(0xFD);
2353
0
                0x9Du32.encode(sink);
2354
0
            }
2355
0
            Instruction::I16x8ExtMulLowI8x16U => {
2356
0
                sink.push(0xFD);
2357
0
                0x9Eu32.encode(sink);
2358
0
            }
2359
0
            Instruction::I16x8ExtMulHighI8x16U => {
2360
0
                sink.push(0xFD);
2361
0
                0x9Fu32.encode(sink);
2362
0
            }
2363
0
            Instruction::I32x4Abs => {
2364
0
                sink.push(0xFD);
2365
0
                0xA0u32.encode(sink);
2366
0
            }
2367
0
            Instruction::I32x4Neg => {
2368
0
                sink.push(0xFD);
2369
0
                0xA1u32.encode(sink);
2370
0
            }
2371
0
            Instruction::I32x4AllTrue => {
2372
0
                sink.push(0xFD);
2373
0
                0xA3u32.encode(sink);
2374
0
            }
2375
0
            Instruction::I32x4Bitmask => {
2376
0
                sink.push(0xFD);
2377
0
                0xA4u32.encode(sink);
2378
0
            }
2379
0
            Instruction::I32x4ExtendLowI16x8S => {
2380
0
                sink.push(0xFD);
2381
0
                0xA7u32.encode(sink);
2382
0
            }
2383
0
            Instruction::I32x4ExtendHighI16x8S => {
2384
0
                sink.push(0xFD);
2385
0
                0xA8u32.encode(sink);
2386
0
            }
2387
0
            Instruction::I32x4ExtendLowI16x8U => {
2388
0
                sink.push(0xFD);
2389
0
                0xA9u32.encode(sink);
2390
0
            }
2391
0
            Instruction::I32x4ExtendHighI16x8U => {
2392
0
                sink.push(0xFD);
2393
0
                0xAAu32.encode(sink);
2394
0
            }
2395
0
            Instruction::I32x4Shl => {
2396
0
                sink.push(0xFD);
2397
0
                0xABu32.encode(sink);
2398
0
            }
2399
0
            Instruction::I32x4ShrS => {
2400
0
                sink.push(0xFD);
2401
0
                0xACu32.encode(sink);
2402
0
            }
2403
0
            Instruction::I32x4ShrU => {
2404
0
                sink.push(0xFD);
2405
0
                0xADu32.encode(sink);
2406
0
            }
2407
0
            Instruction::I32x4Add => {
2408
0
                sink.push(0xFD);
2409
0
                0xAEu32.encode(sink);
2410
0
            }
2411
0
            Instruction::I32x4Sub => {
2412
0
                sink.push(0xFD);
2413
0
                0xB1u32.encode(sink);
2414
0
            }
2415
0
            Instruction::I32x4Mul => {
2416
0
                sink.push(0xFD);
2417
0
                0xB5u32.encode(sink);
2418
0
            }
2419
0
            Instruction::I32x4MinS => {
2420
0
                sink.push(0xFD);
2421
0
                0xB6u32.encode(sink);
2422
0
            }
2423
0
            Instruction::I32x4MinU => {
2424
0
                sink.push(0xFD);
2425
0
                0xB7u32.encode(sink);
2426
0
            }
2427
0
            Instruction::I32x4MaxS => {
2428
0
                sink.push(0xFD);
2429
0
                0xB8u32.encode(sink);
2430
0
            }
2431
0
            Instruction::I32x4MaxU => {
2432
0
                sink.push(0xFD);
2433
0
                0xB9u32.encode(sink);
2434
0
            }
2435
0
            Instruction::I32x4DotI16x8S => {
2436
0
                sink.push(0xFD);
2437
0
                0xBAu32.encode(sink);
2438
0
            }
2439
0
            Instruction::I32x4ExtMulLowI16x8S => {
2440
0
                sink.push(0xFD);
2441
0
                0xBCu32.encode(sink);
2442
0
            }
2443
0
            Instruction::I32x4ExtMulHighI16x8S => {
2444
0
                sink.push(0xFD);
2445
0
                0xBDu32.encode(sink);
2446
0
            }
2447
0
            Instruction::I32x4ExtMulLowI16x8U => {
2448
0
                sink.push(0xFD);
2449
0
                0xBEu32.encode(sink);
2450
0
            }
2451
0
            Instruction::I32x4ExtMulHighI16x8U => {
2452
0
                sink.push(0xFD);
2453
0
                0xBFu32.encode(sink);
2454
0
            }
2455
0
            Instruction::I64x2Abs => {
2456
0
                sink.push(0xFD);
2457
0
                0xC0u32.encode(sink);
2458
0
            }
2459
0
            Instruction::I64x2Neg => {
2460
0
                sink.push(0xFD);
2461
0
                0xC1u32.encode(sink);
2462
0
            }
2463
0
            Instruction::I64x2AllTrue => {
2464
0
                sink.push(0xFD);
2465
0
                0xC3u32.encode(sink);
2466
0
            }
2467
0
            Instruction::I64x2Bitmask => {
2468
0
                sink.push(0xFD);
2469
0
                0xC4u32.encode(sink);
2470
0
            }
2471
0
            Instruction::I64x2ExtendLowI32x4S => {
2472
0
                sink.push(0xFD);
2473
0
                0xC7u32.encode(sink);
2474
0
            }
2475
0
            Instruction::I64x2ExtendHighI32x4S => {
2476
0
                sink.push(0xFD);
2477
0
                0xC8u32.encode(sink);
2478
0
            }
2479
0
            Instruction::I64x2ExtendLowI32x4U => {
2480
0
                sink.push(0xFD);
2481
0
                0xC9u32.encode(sink);
2482
0
            }
2483
0
            Instruction::I64x2ExtendHighI32x4U => {
2484
0
                sink.push(0xFD);
2485
0
                0xCAu32.encode(sink);
2486
0
            }
2487
0
            Instruction::I64x2Shl => {
2488
0
                sink.push(0xFD);
2489
0
                0xCBu32.encode(sink);
2490
0
            }
2491
0
            Instruction::I64x2ShrS => {
2492
0
                sink.push(0xFD);
2493
0
                0xCCu32.encode(sink);
2494
0
            }
2495
0
            Instruction::I64x2ShrU => {
2496
0
                sink.push(0xFD);
2497
0
                0xCDu32.encode(sink);
2498
0
            }
2499
0
            Instruction::I64x2Add => {
2500
0
                sink.push(0xFD);
2501
0
                0xCEu32.encode(sink);
2502
0
            }
2503
0
            Instruction::I64x2Sub => {
2504
0
                sink.push(0xFD);
2505
0
                0xD1u32.encode(sink);
2506
0
            }
2507
0
            Instruction::I64x2Mul => {
2508
0
                sink.push(0xFD);
2509
0
                0xD5u32.encode(sink);
2510
0
            }
2511
0
            Instruction::I64x2ExtMulLowI32x4S => {
2512
0
                sink.push(0xFD);
2513
0
                0xDCu32.encode(sink);
2514
0
            }
2515
0
            Instruction::I64x2ExtMulHighI32x4S => {
2516
0
                sink.push(0xFD);
2517
0
                0xDDu32.encode(sink);
2518
0
            }
2519
0
            Instruction::I64x2ExtMulLowI32x4U => {
2520
0
                sink.push(0xFD);
2521
0
                0xDEu32.encode(sink);
2522
0
            }
2523
0
            Instruction::I64x2ExtMulHighI32x4U => {
2524
0
                sink.push(0xFD);
2525
0
                0xDFu32.encode(sink);
2526
0
            }
2527
0
            Instruction::F32x4Ceil => {
2528
0
                sink.push(0xFD);
2529
0
                0x67u32.encode(sink);
2530
0
            }
2531
0
            Instruction::F32x4Floor => {
2532
0
                sink.push(0xFD);
2533
0
                0x68u32.encode(sink);
2534
0
            }
2535
0
            Instruction::F32x4Trunc => {
2536
0
                sink.push(0xFD);
2537
0
                0x69u32.encode(sink);
2538
0
            }
2539
0
            Instruction::F32x4Nearest => {
2540
0
                sink.push(0xFD);
2541
0
                0x6Au32.encode(sink);
2542
0
            }
2543
0
            Instruction::F32x4Abs => {
2544
0
                sink.push(0xFD);
2545
0
                0xE0u32.encode(sink);
2546
0
            }
2547
0
            Instruction::F32x4Neg => {
2548
0
                sink.push(0xFD);
2549
0
                0xE1u32.encode(sink);
2550
0
            }
2551
0
            Instruction::F32x4Sqrt => {
2552
0
                sink.push(0xFD);
2553
0
                0xE3u32.encode(sink);
2554
0
            }
2555
0
            Instruction::F32x4Add => {
2556
0
                sink.push(0xFD);
2557
0
                0xE4u32.encode(sink);
2558
0
            }
2559
0
            Instruction::F32x4Sub => {
2560
0
                sink.push(0xFD);
2561
0
                0xE5u32.encode(sink);
2562
0
            }
2563
0
            Instruction::F32x4Mul => {
2564
0
                sink.push(0xFD);
2565
0
                0xE6u32.encode(sink);
2566
0
            }
2567
0
            Instruction::F32x4Div => {
2568
0
                sink.push(0xFD);
2569
0
                0xE7u32.encode(sink);
2570
0
            }
2571
0
            Instruction::F32x4Min => {
2572
0
                sink.push(0xFD);
2573
0
                0xE8u32.encode(sink);
2574
0
            }
2575
0
            Instruction::F32x4Max => {
2576
0
                sink.push(0xFD);
2577
0
                0xE9u32.encode(sink);
2578
0
            }
2579
0
            Instruction::F32x4PMin => {
2580
0
                sink.push(0xFD);
2581
0
                0xEAu32.encode(sink);
2582
0
            }
2583
0
            Instruction::F32x4PMax => {
2584
0
                sink.push(0xFD);
2585
0
                0xEBu32.encode(sink);
2586
0
            }
2587
0
            Instruction::F64x2Ceil => {
2588
0
                sink.push(0xFD);
2589
0
                0x74u32.encode(sink);
2590
0
            }
2591
0
            Instruction::F64x2Floor => {
2592
0
                sink.push(0xFD);
2593
0
                0x75u32.encode(sink);
2594
0
            }
2595
0
            Instruction::F64x2Trunc => {
2596
0
                sink.push(0xFD);
2597
0
                0x7Au32.encode(sink);
2598
0
            }
2599
0
            Instruction::F64x2Nearest => {
2600
0
                sink.push(0xFD);
2601
0
                0x94u32.encode(sink);
2602
0
            }
2603
0
            Instruction::F64x2Abs => {
2604
0
                sink.push(0xFD);
2605
0
                0xECu32.encode(sink);
2606
0
            }
2607
0
            Instruction::F64x2Neg => {
2608
0
                sink.push(0xFD);
2609
0
                0xEDu32.encode(sink);
2610
0
            }
2611
0
            Instruction::F64x2Sqrt => {
2612
0
                sink.push(0xFD);
2613
0
                0xEFu32.encode(sink);
2614
0
            }
2615
0
            Instruction::F64x2Add => {
2616
0
                sink.push(0xFD);
2617
0
                0xF0u32.encode(sink);
2618
0
            }
2619
0
            Instruction::F64x2Sub => {
2620
0
                sink.push(0xFD);
2621
0
                0xF1u32.encode(sink);
2622
0
            }
2623
0
            Instruction::F64x2Mul => {
2624
0
                sink.push(0xFD);
2625
0
                0xF2u32.encode(sink);
2626
0
            }
2627
0
            Instruction::F64x2Div => {
2628
0
                sink.push(0xFD);
2629
0
                0xF3u32.encode(sink);
2630
0
            }
2631
0
            Instruction::F64x2Min => {
2632
0
                sink.push(0xFD);
2633
0
                0xF4u32.encode(sink);
2634
0
            }
2635
0
            Instruction::F64x2Max => {
2636
0
                sink.push(0xFD);
2637
0
                0xF5u32.encode(sink);
2638
0
            }
2639
0
            Instruction::F64x2PMin => {
2640
0
                sink.push(0xFD);
2641
0
                0xF6u32.encode(sink);
2642
0
            }
2643
0
            Instruction::F64x2PMax => {
2644
0
                sink.push(0xFD);
2645
0
                0xF7u32.encode(sink);
2646
0
            }
2647
0
            Instruction::I32x4TruncSatF32x4S => {
2648
0
                sink.push(0xFD);
2649
0
                0xF8u32.encode(sink);
2650
0
            }
2651
0
            Instruction::I32x4TruncSatF32x4U => {
2652
0
                sink.push(0xFD);
2653
0
                0xF9u32.encode(sink);
2654
0
            }
2655
0
            Instruction::F32x4ConvertI32x4S => {
2656
0
                sink.push(0xFD);
2657
0
                0xFAu32.encode(sink);
2658
0
            }
2659
0
            Instruction::F32x4ConvertI32x4U => {
2660
0
                sink.push(0xFD);
2661
0
                0xFBu32.encode(sink);
2662
0
            }
2663
0
            Instruction::I32x4TruncSatF64x2SZero => {
2664
0
                sink.push(0xFD);
2665
0
                0xFCu32.encode(sink);
2666
0
            }
2667
0
            Instruction::I32x4TruncSatF64x2UZero => {
2668
0
                sink.push(0xFD);
2669
0
                0xFDu32.encode(sink);
2670
0
            }
2671
0
            Instruction::F64x2ConvertLowI32x4S => {
2672
0
                sink.push(0xFD);
2673
0
                0xFEu32.encode(sink);
2674
0
            }
2675
0
            Instruction::F64x2ConvertLowI32x4U => {
2676
0
                sink.push(0xFD);
2677
0
                0xFFu32.encode(sink);
2678
0
            }
2679
0
            Instruction::F32x4DemoteF64x2Zero => {
2680
0
                sink.push(0xFD);
2681
0
                0x5Eu32.encode(sink);
2682
0
            }
2683
0
            Instruction::F64x2PromoteLowF32x4 => {
2684
0
                sink.push(0xFD);
2685
0
                0x5Fu32.encode(sink);
2686
0
            }
2687
0
            Instruction::V128Load32Zero(memarg) => {
2688
0
                sink.push(0xFD);
2689
0
                0x5Cu32.encode(sink);
2690
0
                memarg.encode(sink);
2691
0
            }
2692
0
            Instruction::V128Load64Zero(memarg) => {
2693
0
                sink.push(0xFD);
2694
0
                0x5Du32.encode(sink);
2695
0
                memarg.encode(sink);
2696
0
            }
2697
0
            Instruction::V128Load8Lane { memarg, lane } => {
2698
0
                sink.push(0xFD);
2699
0
                0x54u32.encode(sink);
2700
0
                memarg.encode(sink);
2701
0
                assert!(lane < 16);
2702
0
                sink.push(lane);
2703
            }
2704
0
            Instruction::V128Load16Lane { memarg, lane } => {
2705
0
                sink.push(0xFD);
2706
0
                0x55u32.encode(sink);
2707
0
                memarg.encode(sink);
2708
0
                assert!(lane < 8);
2709
0
                sink.push(lane);
2710
            }
2711
0
            Instruction::V128Load32Lane { memarg, lane } => {
2712
0
                sink.push(0xFD);
2713
0
                0x56u32.encode(sink);
2714
0
                memarg.encode(sink);
2715
0
                assert!(lane < 4);
2716
0
                sink.push(lane);
2717
            }
2718
0
            Instruction::V128Load64Lane { memarg, lane } => {
2719
0
                sink.push(0xFD);
2720
0
                0x57u32.encode(sink);
2721
0
                memarg.encode(sink);
2722
0
                assert!(lane < 2);
2723
0
                sink.push(lane);
2724
            }
2725
0
            Instruction::V128Store8Lane { memarg, lane } => {
2726
0
                sink.push(0xFD);
2727
0
                0x58u32.encode(sink);
2728
0
                memarg.encode(sink);
2729
0
                assert!(lane < 16);
2730
0
                sink.push(lane);
2731
            }
2732
0
            Instruction::V128Store16Lane { memarg, lane } => {
2733
0
                sink.push(0xFD);
2734
0
                0x59u32.encode(sink);
2735
0
                memarg.encode(sink);
2736
0
                assert!(lane < 8);
2737
0
                sink.push(lane);
2738
            }
2739
0
            Instruction::V128Store32Lane { memarg, lane } => {
2740
0
                sink.push(0xFD);
2741
0
                0x5Au32.encode(sink);
2742
0
                memarg.encode(sink);
2743
0
                assert!(lane < 4);
2744
0
                sink.push(lane);
2745
            }
2746
0
            Instruction::V128Store64Lane { memarg, lane } => {
2747
0
                sink.push(0xFD);
2748
0
                0x5Bu32.encode(sink);
2749
0
                memarg.encode(sink);
2750
0
                assert!(lane < 2);
2751
0
                sink.push(lane);
2752
            }
2753
0
            Instruction::I64x2Eq => {
2754
0
                sink.push(0xFD);
2755
0
                0xD6u32.encode(sink);
2756
0
            }
2757
0
            Instruction::I64x2Ne => {
2758
0
                sink.push(0xFD);
2759
0
                0xD7u32.encode(sink);
2760
0
            }
2761
0
            Instruction::I64x2LtS => {
2762
0
                sink.push(0xFD);
2763
0
                0xD8u32.encode(sink);
2764
0
            }
2765
0
            Instruction::I64x2GtS => {
2766
0
                sink.push(0xFD);
2767
0
                0xD9u32.encode(sink);
2768
0
            }
2769
0
            Instruction::I64x2LeS => {
2770
0
                sink.push(0xFD);
2771
0
                0xDAu32.encode(sink);
2772
0
            }
2773
0
            Instruction::I64x2GeS => {
2774
0
                sink.push(0xFD);
2775
0
                0xDBu32.encode(sink);
2776
0
            }
2777
0
            Instruction::I8x16RelaxedSwizzle => {
2778
0
                sink.push(0xFD);
2779
0
                0x100u32.encode(sink);
2780
0
            }
2781
0
            Instruction::I32x4RelaxedTruncF32x4S => {
2782
0
                sink.push(0xFD);
2783
0
                0x101u32.encode(sink);
2784
0
            }
2785
0
            Instruction::I32x4RelaxedTruncF32x4U => {
2786
0
                sink.push(0xFD);
2787
0
                0x102u32.encode(sink);
2788
0
            }
2789
0
            Instruction::I32x4RelaxedTruncF64x2SZero => {
2790
0
                sink.push(0xFD);
2791
0
                0x103u32.encode(sink);
2792
0
            }
2793
0
            Instruction::I32x4RelaxedTruncF64x2UZero => {
2794
0
                sink.push(0xFD);
2795
0
                0x104u32.encode(sink);
2796
0
            }
2797
0
            Instruction::F32x4RelaxedMadd => {
2798
0
                sink.push(0xFD);
2799
0
                0x105u32.encode(sink);
2800
0
            }
2801
0
            Instruction::F32x4RelaxedNmadd => {
2802
0
                sink.push(0xFD);
2803
0
                0x106u32.encode(sink);
2804
0
            }
2805
0
            Instruction::F64x2RelaxedMadd => {
2806
0
                sink.push(0xFD);
2807
0
                0x107u32.encode(sink);
2808
0
            }
2809
0
            Instruction::F64x2RelaxedNmadd => {
2810
0
                sink.push(0xFD);
2811
0
                0x108u32.encode(sink);
2812
0
            }
2813
0
            Instruction::I8x16RelaxedLaneselect => {
2814
0
                sink.push(0xFD);
2815
0
                0x109u32.encode(sink);
2816
0
            }
2817
0
            Instruction::I16x8RelaxedLaneselect => {
2818
0
                sink.push(0xFD);
2819
0
                0x10Au32.encode(sink);
2820
0
            }
2821
0
            Instruction::I32x4RelaxedLaneselect => {
2822
0
                sink.push(0xFD);
2823
0
                0x10Bu32.encode(sink);
2824
0
            }
2825
0
            Instruction::I64x2RelaxedLaneselect => {
2826
0
                sink.push(0xFD);
2827
0
                0x10Cu32.encode(sink);
2828
0
            }
2829
0
            Instruction::F32x4RelaxedMin => {
2830
0
                sink.push(0xFD);
2831
0
                0x10Du32.encode(sink);
2832
0
            }
2833
0
            Instruction::F32x4RelaxedMax => {
2834
0
                sink.push(0xFD);
2835
0
                0x10Eu32.encode(sink);
2836
0
            }
2837
0
            Instruction::F64x2RelaxedMin => {
2838
0
                sink.push(0xFD);
2839
0
                0x10Fu32.encode(sink);
2840
0
            }
2841
0
            Instruction::F64x2RelaxedMax => {
2842
0
                sink.push(0xFD);
2843
0
                0x110u32.encode(sink);
2844
0
            }
2845
0
            Instruction::I16x8RelaxedQ15mulrS => {
2846
0
                sink.push(0xFD);
2847
0
                0x111u32.encode(sink);
2848
0
            }
2849
0
            Instruction::I16x8RelaxedDotI8x16I7x16S => {
2850
0
                sink.push(0xFD);
2851
0
                0x112u32.encode(sink);
2852
0
            }
2853
0
            Instruction::I32x4RelaxedDotI8x16I7x16AddS => {
2854
0
                sink.push(0xFD);
2855
0
                0x113u32.encode(sink);
2856
0
            }
2857
2858
            // Atomic instructions from the thread proposal
2859
0
            Instruction::MemoryAtomicNotify(memarg) => {
2860
0
                sink.push(0xFE);
2861
0
                sink.push(0x00);
2862
0
                memarg.encode(sink);
2863
0
            }
2864
0
            Instruction::MemoryAtomicWait32(memarg) => {
2865
0
                sink.push(0xFE);
2866
0
                sink.push(0x01);
2867
0
                memarg.encode(sink);
2868
0
            }
2869
0
            Instruction::MemoryAtomicWait64(memarg) => {
2870
0
                sink.push(0xFE);
2871
0
                sink.push(0x02);
2872
0
                memarg.encode(sink);
2873
0
            }
2874
0
            Instruction::AtomicFence => {
2875
0
                sink.push(0xFE);
2876
0
                sink.push(0x03);
2877
0
                sink.push(0x00);
2878
0
            }
2879
0
            Instruction::I32AtomicLoad(memarg) => {
2880
0
                sink.push(0xFE);
2881
0
                sink.push(0x10);
2882
0
                memarg.encode(sink);
2883
0
            }
2884
0
            Instruction::I64AtomicLoad(memarg) => {
2885
0
                sink.push(0xFE);
2886
0
                sink.push(0x11);
2887
0
                memarg.encode(sink);
2888
0
            }
2889
0
            Instruction::I32AtomicLoad8U(memarg) => {
2890
0
                sink.push(0xFE);
2891
0
                sink.push(0x12);
2892
0
                memarg.encode(sink);
2893
0
            }
2894
0
            Instruction::I32AtomicLoad16U(memarg) => {
2895
0
                sink.push(0xFE);
2896
0
                sink.push(0x13);
2897
0
                memarg.encode(sink);
2898
0
            }
2899
0
            Instruction::I64AtomicLoad8U(memarg) => {
2900
0
                sink.push(0xFE);
2901
0
                sink.push(0x14);
2902
0
                memarg.encode(sink);
2903
0
            }
2904
0
            Instruction::I64AtomicLoad16U(memarg) => {
2905
0
                sink.push(0xFE);
2906
0
                sink.push(0x15);
2907
0
                memarg.encode(sink);
2908
0
            }
2909
0
            Instruction::I64AtomicLoad32U(memarg) => {
2910
0
                sink.push(0xFE);
2911
0
                sink.push(0x16);
2912
0
                memarg.encode(sink);
2913
0
            }
2914
0
            Instruction::I32AtomicStore(memarg) => {
2915
0
                sink.push(0xFE);
2916
0
                sink.push(0x17);
2917
0
                memarg.encode(sink);
2918
0
            }
2919
0
            Instruction::I64AtomicStore(memarg) => {
2920
0
                sink.push(0xFE);
2921
0
                sink.push(0x18);
2922
0
                memarg.encode(sink);
2923
0
            }
2924
0
            Instruction::I32AtomicStore8(memarg) => {
2925
0
                sink.push(0xFE);
2926
0
                sink.push(0x19);
2927
0
                memarg.encode(sink);
2928
0
            }
2929
0
            Instruction::I32AtomicStore16(memarg) => {
2930
0
                sink.push(0xFE);
2931
0
                sink.push(0x1A);
2932
0
                memarg.encode(sink);
2933
0
            }
2934
0
            Instruction::I64AtomicStore8(memarg) => {
2935
0
                sink.push(0xFE);
2936
0
                sink.push(0x1B);
2937
0
                memarg.encode(sink);
2938
0
            }
2939
0
            Instruction::I64AtomicStore16(memarg) => {
2940
0
                sink.push(0xFE);
2941
0
                sink.push(0x1C);
2942
0
                memarg.encode(sink);
2943
0
            }
2944
0
            Instruction::I64AtomicStore32(memarg) => {
2945
0
                sink.push(0xFE);
2946
0
                sink.push(0x1D);
2947
0
                memarg.encode(sink);
2948
0
            }
2949
0
            Instruction::I32AtomicRmwAdd(memarg) => {
2950
0
                sink.push(0xFE);
2951
0
                sink.push(0x1E);
2952
0
                memarg.encode(sink);
2953
0
            }
2954
0
            Instruction::I64AtomicRmwAdd(memarg) => {
2955
0
                sink.push(0xFE);
2956
0
                sink.push(0x1F);
2957
0
                memarg.encode(sink);
2958
0
            }
2959
0
            Instruction::I32AtomicRmw8AddU(memarg) => {
2960
0
                sink.push(0xFE);
2961
0
                sink.push(0x20);
2962
0
                memarg.encode(sink);
2963
0
            }
2964
0
            Instruction::I32AtomicRmw16AddU(memarg) => {
2965
0
                sink.push(0xFE);
2966
0
                sink.push(0x21);
2967
0
                memarg.encode(sink);
2968
0
            }
2969
0
            Instruction::I64AtomicRmw8AddU(memarg) => {
2970
0
                sink.push(0xFE);
2971
0
                sink.push(0x22);
2972
0
                memarg.encode(sink);
2973
0
            }
2974
0
            Instruction::I64AtomicRmw16AddU(memarg) => {
2975
0
                sink.push(0xFE);
2976
0
                sink.push(0x23);
2977
0
                memarg.encode(sink);
2978
0
            }
2979
0
            Instruction::I64AtomicRmw32AddU(memarg) => {
2980
0
                sink.push(0xFE);
2981
0
                sink.push(0x24);
2982
0
                memarg.encode(sink);
2983
0
            }
2984
0
            Instruction::I32AtomicRmwSub(memarg) => {
2985
0
                sink.push(0xFE);
2986
0
                sink.push(0x25);
2987
0
                memarg.encode(sink);
2988
0
            }
2989
0
            Instruction::I64AtomicRmwSub(memarg) => {
2990
0
                sink.push(0xFE);
2991
0
                sink.push(0x26);
2992
0
                memarg.encode(sink);
2993
0
            }
2994
0
            Instruction::I32AtomicRmw8SubU(memarg) => {
2995
0
                sink.push(0xFE);
2996
0
                sink.push(0x27);
2997
0
                memarg.encode(sink);
2998
0
            }
2999
0
            Instruction::I32AtomicRmw16SubU(memarg) => {
3000
0
                sink.push(0xFE);
3001
0
                sink.push(0x28);
3002
0
                memarg.encode(sink);
3003
0
            }
3004
0
            Instruction::I64AtomicRmw8SubU(memarg) => {
3005
0
                sink.push(0xFE);
3006
0
                sink.push(0x29);
3007
0
                memarg.encode(sink);
3008
0
            }
3009
0
            Instruction::I64AtomicRmw16SubU(memarg) => {
3010
0
                sink.push(0xFE);
3011
0
                sink.push(0x2A);
3012
0
                memarg.encode(sink);
3013
0
            }
3014
0
            Instruction::I64AtomicRmw32SubU(memarg) => {
3015
0
                sink.push(0xFE);
3016
0
                sink.push(0x2B);
3017
0
                memarg.encode(sink);
3018
0
            }
3019
0
            Instruction::I32AtomicRmwAnd(memarg) => {
3020
0
                sink.push(0xFE);
3021
0
                sink.push(0x2C);
3022
0
                memarg.encode(sink);
3023
0
            }
3024
0
            Instruction::I64AtomicRmwAnd(memarg) => {
3025
0
                sink.push(0xFE);
3026
0
                sink.push(0x2D);
3027
0
                memarg.encode(sink);
3028
0
            }
3029
0
            Instruction::I32AtomicRmw8AndU(memarg) => {
3030
0
                sink.push(0xFE);
3031
0
                sink.push(0x2E);
3032
0
                memarg.encode(sink);
3033
0
            }
3034
0
            Instruction::I32AtomicRmw16AndU(memarg) => {
3035
0
                sink.push(0xFE);
3036
0
                sink.push(0x2F);
3037
0
                memarg.encode(sink);
3038
0
            }
3039
0
            Instruction::I64AtomicRmw8AndU(memarg) => {
3040
0
                sink.push(0xFE);
3041
0
                sink.push(0x30);
3042
0
                memarg.encode(sink);
3043
0
            }
3044
0
            Instruction::I64AtomicRmw16AndU(memarg) => {
3045
0
                sink.push(0xFE);
3046
0
                sink.push(0x31);
3047
0
                memarg.encode(sink);
3048
0
            }
3049
0
            Instruction::I64AtomicRmw32AndU(memarg) => {
3050
0
                sink.push(0xFE);
3051
0
                sink.push(0x32);
3052
0
                memarg.encode(sink);
3053
0
            }
3054
0
            Instruction::I32AtomicRmwOr(memarg) => {
3055
0
                sink.push(0xFE);
3056
0
                sink.push(0x33);
3057
0
                memarg.encode(sink);
3058
0
            }
3059
0
            Instruction::I64AtomicRmwOr(memarg) => {
3060
0
                sink.push(0xFE);
3061
0
                sink.push(0x34);
3062
0
                memarg.encode(sink);
3063
0
            }
3064
0
            Instruction::I32AtomicRmw8OrU(memarg) => {
3065
0
                sink.push(0xFE);
3066
0
                sink.push(0x35);
3067
0
                memarg.encode(sink);
3068
0
            }
3069
0
            Instruction::I32AtomicRmw16OrU(memarg) => {
3070
0
                sink.push(0xFE);
3071
0
                sink.push(0x36);
3072
0
                memarg.encode(sink);
3073
0
            }
3074
0
            Instruction::I64AtomicRmw8OrU(memarg) => {
3075
0
                sink.push(0xFE);
3076
0
                sink.push(0x37);
3077
0
                memarg.encode(sink);
3078
0
            }
3079
0
            Instruction::I64AtomicRmw16OrU(memarg) => {
3080
0
                sink.push(0xFE);
3081
0
                sink.push(0x38);
3082
0
                memarg.encode(sink);
3083
0
            }
3084
0
            Instruction::I64AtomicRmw32OrU(memarg) => {
3085
0
                sink.push(0xFE);
3086
0
                sink.push(0x39);
3087
0
                memarg.encode(sink);
3088
0
            }
3089
0
            Instruction::I32AtomicRmwXor(memarg) => {
3090
0
                sink.push(0xFE);
3091
0
                sink.push(0x3A);
3092
0
                memarg.encode(sink);
3093
0
            }
3094
0
            Instruction::I64AtomicRmwXor(memarg) => {
3095
0
                sink.push(0xFE);
3096
0
                sink.push(0x3B);
3097
0
                memarg.encode(sink);
3098
0
            }
3099
0
            Instruction::I32AtomicRmw8XorU(memarg) => {
3100
0
                sink.push(0xFE);
3101
0
                sink.push(0x3C);
3102
0
                memarg.encode(sink);
3103
0
            }
3104
0
            Instruction::I32AtomicRmw16XorU(memarg) => {
3105
0
                sink.push(0xFE);
3106
0
                sink.push(0x3D);
3107
0
                memarg.encode(sink);
3108
0
            }
3109
0
            Instruction::I64AtomicRmw8XorU(memarg) => {
3110
0
                sink.push(0xFE);
3111
0
                sink.push(0x3E);
3112
0
                memarg.encode(sink);
3113
0
            }
3114
0
            Instruction::I64AtomicRmw16XorU(memarg) => {
3115
0
                sink.push(0xFE);
3116
0
                sink.push(0x3F);
3117
0
                memarg.encode(sink);
3118
0
            }
3119
0
            Instruction::I64AtomicRmw32XorU(memarg) => {
3120
0
                sink.push(0xFE);
3121
0
                sink.push(0x40);
3122
0
                memarg.encode(sink);
3123
0
            }
3124
0
            Instruction::I32AtomicRmwXchg(memarg) => {
3125
0
                sink.push(0xFE);
3126
0
                sink.push(0x41);
3127
0
                memarg.encode(sink);
3128
0
            }
3129
0
            Instruction::I64AtomicRmwXchg(memarg) => {
3130
0
                sink.push(0xFE);
3131
0
                sink.push(0x42);
3132
0
                memarg.encode(sink);
3133
0
            }
3134
0
            Instruction::I32AtomicRmw8XchgU(memarg) => {
3135
0
                sink.push(0xFE);
3136
0
                sink.push(0x43);
3137
0
                memarg.encode(sink);
3138
0
            }
3139
0
            Instruction::I32AtomicRmw16XchgU(memarg) => {
3140
0
                sink.push(0xFE);
3141
0
                sink.push(0x44);
3142
0
                memarg.encode(sink);
3143
0
            }
3144
0
            Instruction::I64AtomicRmw8XchgU(memarg) => {
3145
0
                sink.push(0xFE);
3146
0
                sink.push(0x45);
3147
0
                memarg.encode(sink);
3148
0
            }
3149
0
            Instruction::I64AtomicRmw16XchgU(memarg) => {
3150
0
                sink.push(0xFE);
3151
0
                sink.push(0x46);
3152
0
                memarg.encode(sink);
3153
0
            }
3154
0
            Instruction::I64AtomicRmw32XchgU(memarg) => {
3155
0
                sink.push(0xFE);
3156
0
                sink.push(0x47);
3157
0
                memarg.encode(sink);
3158
0
            }
3159
0
            Instruction::I32AtomicRmwCmpxchg(memarg) => {
3160
0
                sink.push(0xFE);
3161
0
                sink.push(0x48);
3162
0
                memarg.encode(sink);
3163
0
            }
3164
0
            Instruction::I64AtomicRmwCmpxchg(memarg) => {
3165
0
                sink.push(0xFE);
3166
0
                sink.push(0x49);
3167
0
                memarg.encode(sink);
3168
0
            }
3169
0
            Instruction::I32AtomicRmw8CmpxchgU(memarg) => {
3170
0
                sink.push(0xFE);
3171
0
                sink.push(0x4A);
3172
0
                memarg.encode(sink);
3173
0
            }
3174
0
            Instruction::I32AtomicRmw16CmpxchgU(memarg) => {
3175
0
                sink.push(0xFE);
3176
0
                sink.push(0x4B);
3177
0
                memarg.encode(sink);
3178
0
            }
3179
0
            Instruction::I64AtomicRmw8CmpxchgU(memarg) => {
3180
0
                sink.push(0xFE);
3181
0
                sink.push(0x4C);
3182
0
                memarg.encode(sink);
3183
0
            }
3184
0
            Instruction::I64AtomicRmw16CmpxchgU(memarg) => {
3185
0
                sink.push(0xFE);
3186
0
                sink.push(0x4D);
3187
0
                memarg.encode(sink);
3188
0
            }
3189
0
            Instruction::I64AtomicRmw32CmpxchgU(memarg) => {
3190
0
                sink.push(0xFE);
3191
0
                sink.push(0x4E);
3192
0
                memarg.encode(sink);
3193
0
            }
3194
3195
            // Atomic instructions from the shared-everything-threads proposal
3196
            Instruction::GlobalAtomicGet {
3197
0
                ordering,
3198
0
                global_index,
3199
0
            } => {
3200
0
                sink.push(0xFE);
3201
0
                sink.push(0x4F);
3202
0
                ordering.encode(sink);
3203
0
                global_index.encode(sink);
3204
0
            }
3205
            Instruction::GlobalAtomicSet {
3206
0
                ordering,
3207
0
                global_index,
3208
0
            } => {
3209
0
                sink.push(0xFE);
3210
0
                sink.push(0x50);
3211
0
                ordering.encode(sink);
3212
0
                global_index.encode(sink);
3213
0
            }
3214
            Instruction::GlobalAtomicRmwAdd {
3215
0
                ordering,
3216
0
                global_index,
3217
0
            } => {
3218
0
                sink.push(0xFE);
3219
0
                sink.push(0x51);
3220
0
                ordering.encode(sink);
3221
0
                global_index.encode(sink);
3222
0
            }
3223
            Instruction::GlobalAtomicRmwSub {
3224
0
                ordering,
3225
0
                global_index,
3226
0
            } => {
3227
0
                sink.push(0xFE);
3228
0
                sink.push(0x52);
3229
0
                ordering.encode(sink);
3230
0
                global_index.encode(sink);
3231
0
            }
3232
            Instruction::GlobalAtomicRmwAnd {
3233
0
                ordering,
3234
0
                global_index,
3235
0
            } => {
3236
0
                sink.push(0xFE);
3237
0
                sink.push(0x53);
3238
0
                ordering.encode(sink);
3239
0
                global_index.encode(sink);
3240
0
            }
3241
            Instruction::GlobalAtomicRmwOr {
3242
0
                ordering,
3243
0
                global_index,
3244
0
            } => {
3245
0
                sink.push(0xFE);
3246
0
                sink.push(0x54);
3247
0
                ordering.encode(sink);
3248
0
                global_index.encode(sink);
3249
0
            }
3250
            Instruction::GlobalAtomicRmwXor {
3251
0
                ordering,
3252
0
                global_index,
3253
0
            } => {
3254
0
                sink.push(0xFE);
3255
0
                sink.push(0x55);
3256
0
                ordering.encode(sink);
3257
0
                global_index.encode(sink);
3258
0
            }
3259
            Instruction::GlobalAtomicRmwXchg {
3260
0
                ordering,
3261
0
                global_index,
3262
0
            } => {
3263
0
                sink.push(0xFE);
3264
0
                sink.push(0x56);
3265
0
                ordering.encode(sink);
3266
0
                global_index.encode(sink);
3267
0
            }
3268
            Instruction::GlobalAtomicRmwCmpxchg {
3269
0
                ordering,
3270
0
                global_index,
3271
0
            } => {
3272
0
                sink.push(0xFE);
3273
0
                sink.push(0x57);
3274
0
                ordering.encode(sink);
3275
0
                global_index.encode(sink);
3276
0
            }
3277
        }
3278
137k
    }
3279
}
3280
3281
#[derive(Clone, Debug)]
3282
#[allow(missing_docs)]
3283
pub enum Catch {
3284
    One { tag: u32, label: u32 },
3285
    OneRef { tag: u32, label: u32 },
3286
    All { label: u32 },
3287
    AllRef { label: u32 },
3288
}
3289
3290
impl Encode for Catch {
3291
0
    fn encode(&self, sink: &mut Vec<u8>) {
3292
0
        match self {
3293
0
            Catch::One { tag, label } => {
3294
0
                sink.push(0x00);
3295
0
                tag.encode(sink);
3296
0
                label.encode(sink);
3297
0
            }
3298
0
            Catch::OneRef { tag, label } => {
3299
0
                sink.push(0x01);
3300
0
                tag.encode(sink);
3301
0
                label.encode(sink);
3302
0
            }
3303
0
            Catch::All { label } => {
3304
0
                sink.push(0x02);
3305
0
                label.encode(sink);
3306
0
            }
3307
0
            Catch::AllRef { label } => {
3308
0
                sink.push(0x03);
3309
0
                label.encode(sink);
3310
0
            }
3311
        }
3312
0
    }
3313
}
3314
3315
/// A constant expression.
3316
///
3317
/// Usable in contexts such as offsets or initializers.
3318
#[derive(Debug)]
3319
pub struct ConstExpr {
3320
    bytes: Vec<u8>,
3321
}
3322
3323
impl ConstExpr {
3324
    /// Create a new empty constant expression builder.
3325
0
    pub fn empty() -> Self {
3326
0
        Self { bytes: Vec::new() }
3327
0
    }
3328
3329
    /// Create a constant expression with the specified raw encoding of instructions.
3330
0
    pub fn raw(bytes: impl IntoIterator<Item = u8>) -> Self {
3331
0
        Self {
3332
0
            bytes: bytes.into_iter().collect(),
3333
0
        }
3334
0
    }
3335
3336
5.88k
    fn new_insn(insn: Instruction) -> Self {
3337
5.88k
        let mut bytes = vec![];
3338
5.88k
        insn.encode(&mut bytes);
3339
5.88k
        Self { bytes }
3340
5.88k
    }
3341
3342
0
    fn with_insn(mut self, insn: Instruction) -> Self {
3343
0
        insn.encode(&mut self.bytes);
3344
0
        self
3345
0
    }
3346
3347
    /// Create a constant expression containing a single `global.get` instruction.
3348
1.07k
    pub fn global_get(index: u32) -> Self {
3349
1.07k
        Self::new_insn(Instruction::GlobalGet(index))
3350
1.07k
    }
3351
3352
    /// Create a constant expression containing a single `ref.null` instruction.
3353
0
    pub fn ref_null(ty: HeapType) -> Self {
3354
0
        Self::new_insn(Instruction::RefNull(ty))
3355
0
    }
3356
3357
    /// Create a constant expression containing a single `ref.func` instruction.
3358
0
    pub fn ref_func(func: u32) -> Self {
3359
0
        Self::new_insn(Instruction::RefFunc(func))
3360
0
    }
3361
3362
    /// Create a constant expression containing a single `i32.const` instruction.
3363
3.53k
    pub fn i32_const(value: i32) -> Self {
3364
3.53k
        Self::new_insn(Instruction::I32Const(value))
3365
3.53k
    }
3366
3367
    /// Create a constant expression containing a single `i64.const` instruction.
3368
767
    pub fn i64_const(value: i64) -> Self {
3369
767
        Self::new_insn(Instruction::I64Const(value))
3370
767
    }
3371
3372
    /// Create a constant expression containing a single `f32.const` instruction.
3373
320
    pub fn f32_const(value: f32) -> Self {
3374
320
        Self::new_insn(Instruction::F32Const(value))
3375
320
    }
3376
3377
    /// Create a constant expression containing a single `f64.const` instruction.
3378
180
    pub fn f64_const(value: f64) -> Self {
3379
180
        Self::new_insn(Instruction::F64Const(value))
3380
180
    }
3381
3382
    /// Create a constant expression containing a single `v128.const` instruction.
3383
0
    pub fn v128_const(value: i128) -> Self {
3384
0
        Self::new_insn(Instruction::V128Const(value))
3385
0
    }
3386
3387
    /// Add a `global.get` instruction to this constant expression.
3388
0
    pub fn with_global_get(self, index: u32) -> Self {
3389
0
        self.with_insn(Instruction::GlobalGet(index))
3390
0
    }
3391
3392
    /// Add a `ref.null` instruction to this constant expression.
3393
0
    pub fn with_ref_null(self, ty: HeapType) -> Self {
3394
0
        self.with_insn(Instruction::RefNull(ty))
3395
0
    }
3396
3397
    /// Add a `ref.func` instruction to this constant expression.
3398
0
    pub fn with_ref_func(self, func: u32) -> Self {
3399
0
        self.with_insn(Instruction::RefFunc(func))
3400
0
    }
3401
3402
    /// Add an `i32.const` instruction to this constant expression.
3403
0
    pub fn with_i32_const(self, value: i32) -> Self {
3404
0
        self.with_insn(Instruction::I32Const(value))
3405
0
    }
3406
3407
    /// Add an `i64.const` instruction to this constant expression.
3408
0
    pub fn with_i64_const(self, value: i64) -> Self {
3409
0
        self.with_insn(Instruction::I64Const(value))
3410
0
    }
3411
3412
    /// Add a `f32.const` instruction to this constant expression.
3413
0
    pub fn with_f32_const(self, value: f32) -> Self {
3414
0
        self.with_insn(Instruction::F32Const(value))
3415
0
    }
3416
3417
    /// Add a `f64.const` instruction to this constant expression.
3418
0
    pub fn with_f64_const(self, value: f64) -> Self {
3419
0
        self.with_insn(Instruction::F64Const(value))
3420
0
    }
3421
3422
    /// Add a `v128.const` instruction to this constant expression.
3423
0
    pub fn with_v128_const(self, value: i128) -> Self {
3424
0
        self.with_insn(Instruction::V128Const(value))
3425
0
    }
3426
3427
    /// Add an `i32.add` instruction to this constant expression.
3428
0
    pub fn with_i32_add(self) -> Self {
3429
0
        self.with_insn(Instruction::I32Add)
3430
0
    }
3431
3432
    /// Add an `i32.sub` instruction to this constant expression.
3433
0
    pub fn with_i32_sub(self) -> Self {
3434
0
        self.with_insn(Instruction::I32Sub)
3435
0
    }
3436
3437
    /// Add an `i32.mul` instruction to this constant expression.
3438
0
    pub fn with_i32_mul(self) -> Self {
3439
0
        self.with_insn(Instruction::I32Mul)
3440
0
    }
3441
3442
    /// Add an `i64.add` instruction to this constant expression.
3443
0
    pub fn with_i64_add(self) -> Self {
3444
0
        self.with_insn(Instruction::I64Add)
3445
0
    }
3446
3447
    /// Add an `i64.sub` instruction to this constant expression.
3448
0
    pub fn with_i64_sub(self) -> Self {
3449
0
        self.with_insn(Instruction::I64Sub)
3450
0
    }
3451
3452
    /// Add an `i64.mul` instruction to this constant expression.
3453
0
    pub fn with_i64_mul(self) -> Self {
3454
0
        self.with_insn(Instruction::I64Mul)
3455
0
    }
3456
3457
    /// Returns the function, if any, referenced by this global.
3458
2.50k
    pub fn get_ref_func(&self) -> Option<u32> {
3459
2.50k
        let prefix = *self.bytes.get(0)?;
3460
        // 0xd2 == `ref.func` opcode, and if that's found then load the leb
3461
        // corresponding to the function index.
3462
2.50k
        if prefix != 0xd2 {
3463
2.50k
            return None;
3464
0
        }
3465
0
        leb128::read::unsigned(&mut &self.bytes[1..])
3466
0
            .ok()?
3467
0
            .try_into()
3468
0
            .ok()
3469
2.50k
    }
3470
}
3471
3472
impl Encode for ConstExpr {
3473
5.88k
    fn encode(&self, sink: &mut Vec<u8>) {
3474
5.88k
        sink.extend(&self.bytes);
3475
5.88k
        Instruction::End.encode(sink);
3476
5.88k
    }
3477
}
3478
3479
/// An error when converting a `wasmparser::ConstExpr` into a
3480
/// `wasm_encoder::ConstExpr`.
3481
#[cfg(feature = "wasmparser")]
3482
#[derive(Debug)]
3483
pub enum ConstExprConversionError {
3484
    /// There was an error when parsing the const expression.
3485
    ParseError(wasmparser::BinaryReaderError),
3486
3487
    /// The const expression is invalid: not actually constant or something like
3488
    /// that.
3489
    Invalid,
3490
3491
    /// There was a type reference that was canonicalized and no longer
3492
    /// references an index into a module's types space, so we cannot encode it
3493
    /// into a Wasm binary again.
3494
    CanonicalizedTypeReference,
3495
}
3496
3497
#[cfg(feature = "wasmparser")]
3498
impl std::fmt::Display for ConstExprConversionError {
3499
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3500
        match self {
3501
            Self::ParseError(_e) => {
3502
                write!(f, "There was an error when parsing the const expression")
3503
            }
3504
            Self::Invalid => write!(f, "The const expression was invalid"),
3505
            Self::CanonicalizedTypeReference => write!(
3506
                f,
3507
                "There was a canonicalized type reference without type index information"
3508
            ),
3509
        }
3510
    }
3511
}
3512
3513
#[cfg(feature = "wasmparser")]
3514
impl std::error::Error for ConstExprConversionError {
3515
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
3516
        match self {
3517
            Self::ParseError(e) => Some(e),
3518
            Self::Invalid | Self::CanonicalizedTypeReference => None,
3519
        }
3520
    }
3521
}
3522
3523
#[cfg(feature = "wasmparser")]
3524
impl<'a> TryFrom<wasmparser::ConstExpr<'a>> for ConstExpr {
3525
    type Error = ConstExprConversionError;
3526
3527
    fn try_from(const_expr: wasmparser::ConstExpr) -> Result<Self, Self::Error> {
3528
        let mut ops = const_expr.get_operators_reader().into_iter();
3529
3530
        let result = match ops.next() {
3531
            Some(Ok(wasmparser::Operator::I32Const { value })) => ConstExpr::i32_const(value),
3532
            Some(Ok(wasmparser::Operator::I64Const { value })) => ConstExpr::i64_const(value),
3533
            Some(Ok(wasmparser::Operator::F32Const { value })) => {
3534
                ConstExpr::f32_const(f32::from_bits(value.bits()))
3535
            }
3536
            Some(Ok(wasmparser::Operator::F64Const { value })) => {
3537
                ConstExpr::f64_const(f64::from_bits(value.bits()))
3538
            }
3539
            Some(Ok(wasmparser::Operator::V128Const { value })) => {
3540
                ConstExpr::v128_const(i128::from_le_bytes(*value.bytes()))
3541
            }
3542
            Some(Ok(wasmparser::Operator::RefNull { hty })) => ConstExpr::ref_null(
3543
                HeapType::try_from(hty)
3544
                    .map_err(|_| ConstExprConversionError::CanonicalizedTypeReference)?,
3545
            ),
3546
            Some(Ok(wasmparser::Operator::RefFunc { function_index })) => {
3547
                ConstExpr::ref_func(function_index)
3548
            }
3549
            Some(Ok(wasmparser::Operator::GlobalGet { global_index })) => {
3550
                ConstExpr::global_get(global_index)
3551
            }
3552
3553
            // TODO: support the extended-const proposal.
3554
            Some(Ok(_op)) => return Err(ConstExprConversionError::Invalid),
3555
3556
            Some(Err(e)) => return Err(ConstExprConversionError::ParseError(e)),
3557
            None => return Err(ConstExprConversionError::Invalid),
3558
        };
3559
3560
        match (ops.next(), ops.next()) {
3561
            (Some(Ok(wasmparser::Operator::End)), None) => Ok(result),
3562
            _ => Err(ConstExprConversionError::Invalid),
3563
        }
3564
    }
3565
}
3566
3567
#[cfg(test)]
3568
mod tests {
3569
    #[test]
3570
    fn function_new_with_locals_test() {
3571
        use super::*;
3572
3573
        // Test the algorithm for conversion is correct
3574
        let f1 = Function::new_with_locals_types([
3575
            ValType::I32,
3576
            ValType::I32,
3577
            ValType::I64,
3578
            ValType::F32,
3579
            ValType::F32,
3580
            ValType::F32,
3581
            ValType::I32,
3582
            ValType::I64,
3583
            ValType::I64,
3584
        ]);
3585
        let f2 = Function::new([
3586
            (2, ValType::I32),
3587
            (1, ValType::I64),
3588
            (3, ValType::F32),
3589
            (1, ValType::I32),
3590
            (2, ValType::I64),
3591
        ]);
3592
3593
        assert_eq!(f1.bytes, f2.bytes)
3594
    }
3595
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/custom.rs
Line
Count
Source (jump to first uncovered line)
1
use std::borrow::Cow;
2
3
use crate::{encoding_size, Encode, Section, SectionId};
4
5
/// A custom section holding arbitrary data.
6
#[derive(Clone, Debug)]
7
pub struct CustomSection<'a> {
8
    /// The name of this custom section.
9
    pub name: Cow<'a, str>,
10
    /// This custom section's data.
11
    pub data: Cow<'a, [u8]>,
12
}
13
14
impl Encode for CustomSection<'_> {
15
0
    fn encode(&self, sink: &mut Vec<u8>) {
16
0
        let encoded_name_len = encoding_size(u32::try_from(self.name.len()).unwrap());
17
0
        (encoded_name_len + self.name.len() + self.data.len()).encode(sink);
18
0
        self.name.encode(sink);
19
0
        sink.extend(&*self.data);
20
0
    }
21
}
22
23
impl Section for CustomSection<'_> {
24
0
    fn id(&self) -> u8 {
25
0
        SectionId::Custom.into()
26
0
    }
27
}
28
29
/// A raw custom section where the bytes specified contain the leb-encoded
30
/// length of the custom section, the custom section's name, and the custom
31
/// section's data.
32
#[derive(Clone, Debug)]
33
pub struct RawCustomSection<'a>(pub &'a [u8]);
34
35
impl Encode for RawCustomSection<'_> {
36
0
    fn encode(&self, sink: &mut Vec<u8>) {
37
0
        sink.extend(self.0);
38
0
    }
39
}
40
41
impl Section for RawCustomSection<'_> {
42
0
    fn id(&self) -> u8 {
43
0
        SectionId::Custom.into()
44
0
    }
45
}
46
47
#[cfg(test)]
48
mod tests {
49
    use super::*;
50
51
    #[test]
52
    fn test_custom_section() {
53
        let custom = CustomSection {
54
            name: "test".into(),
55
            data: Cow::Borrowed(&[11, 22, 33, 44]),
56
        };
57
58
        let mut encoded = vec![];
59
        custom.encode(&mut encoded);
60
61
        #[rustfmt::skip]
62
        assert_eq!(encoded, vec![
63
            // LEB128 length of section.
64
            9,
65
            // LEB128 length of name.
66
            4,
67
            // Name.
68
            b't', b'e', b's', b't',
69
            // Data.
70
            11, 22, 33, 44,
71
        ]);
72
    }
73
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/data.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, encoding_size, ConstExpr, Encode, Section, SectionId};
2
3
/// An encoder for the data section.
4
///
5
/// Data sections are only supported for modules.
6
///
7
/// # Example
8
///
9
/// ```
10
/// use wasm_encoder::{
11
///     ConstExpr, DataSection, Instruction, MemorySection, MemoryType,
12
///     Module,
13
/// };
14
///
15
/// let mut memory = MemorySection::new();
16
/// memory.memory(MemoryType {
17
///     minimum: 1,
18
///     maximum: None,
19
///     memory64: false,
20
///     shared: false,
21
///     page_size_log2: None,
22
/// });
23
///
24
/// let mut data = DataSection::new();
25
/// let memory_index = 0;
26
/// let offset = ConstExpr::i32_const(42);
27
/// let segment_data = b"hello";
28
/// data.active(memory_index, &offset, segment_data.iter().copied());
29
///
30
/// let mut module = Module::new();
31
/// module
32
///     .section(&memory)
33
///     .section(&data);
34
///
35
/// let wasm_bytes = module.finish();
36
/// ```
37
#[derive(Clone, Default, Debug)]
38
pub struct DataSection {
39
    bytes: Vec<u8>,
40
    num_added: u32,
41
}
42
43
/// A segment in the data section.
44
#[derive(Clone, Debug)]
45
pub struct DataSegment<'a, D> {
46
    /// This data segment's mode.
47
    pub mode: DataSegmentMode<'a>,
48
    /// This data segment's data.
49
    pub data: D,
50
}
51
52
/// A data segment's mode.
53
#[derive(Clone, Debug)]
54
pub enum DataSegmentMode<'a> {
55
    /// An active data segment.
56
    Active {
57
        /// The memory this segment applies to.
58
        memory_index: u32,
59
        /// The offset where this segment's data is initialized at.
60
        offset: &'a ConstExpr,
61
    },
62
    /// A passive data segment.
63
    ///
64
    /// Passive data segments are part of the bulk memory proposal.
65
    Passive,
66
}
67
68
impl DataSection {
69
    /// Create a new data section encoder.
70
176
    pub fn new() -> Self {
71
176
        Self::default()
72
176
    }
_RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB2_11DataSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
70
176
    pub fn new() -> Self {
71
176
        Self::default()
72
176
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB2_11DataSection3newB6_
73
74
    /// The number of data segments in the section.
75
0
    pub fn len(&self) -> u32 {
76
0
        self.num_added
77
0
    }
78
79
    /// Determines if the section is empty.
80
0
    pub fn is_empty(&self) -> bool {
81
0
        self.num_added == 0
82
0
    }
83
84
    /// Define a data segment.
85
776
    pub fn segment<D>(&mut self, segment: DataSegment<D>) -> &mut Self
86
776
    where
87
776
        D: IntoIterator<Item = u8>,
88
776
        D::IntoIter: ExactSizeIterator,
89
776
    {
90
776
        match segment.mode {
91
0
            DataSegmentMode::Passive => {
92
0
                self.bytes.push(0x01);
93
0
            }
94
            DataSegmentMode::Active {
95
                memory_index: 0,
96
776
                offset,
97
776
            } => {
98
776
                self.bytes.push(0x00);
99
776
                offset.encode(&mut self.bytes);
100
776
            }
101
            DataSegmentMode::Active {
102
0
                memory_index,
103
0
                offset,
104
0
            } => {
105
0
                self.bytes.push(0x02);
106
0
                memory_index.encode(&mut self.bytes);
107
0
                offset.encode(&mut self.bytes);
108
0
            }
109
        }
110
111
776
        let data = segment.data.into_iter();
112
776
        data.len().encode(&mut self.bytes);
113
776
        self.bytes.extend(data);
114
776
115
776
        self.num_added += 1;
116
776
        self
117
776
    }
_RINvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB3_11DataSection7segmentINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1i_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
85
776
    pub fn segment<D>(&mut self, segment: DataSegment<D>) -> &mut Self
86
776
    where
87
776
        D: IntoIterator<Item = u8>,
88
776
        D::IntoIter: ExactSizeIterator,
89
776
    {
90
776
        match segment.mode {
91
0
            DataSegmentMode::Passive => {
92
0
                self.bytes.push(0x01);
93
0
            }
94
            DataSegmentMode::Active {
95
                memory_index: 0,
96
776
                offset,
97
776
            } => {
98
776
                self.bytes.push(0x00);
99
776
                offset.encode(&mut self.bytes);
100
776
            }
101
            DataSegmentMode::Active {
102
0
                memory_index,
103
0
                offset,
104
0
            } => {
105
0
                self.bytes.push(0x02);
106
0
                memory_index.encode(&mut self.bytes);
107
0
                offset.encode(&mut self.bytes);
108
0
            }
109
        }
110
111
776
        let data = segment.data.into_iter();
112
776
        data.len().encode(&mut self.bytes);
113
776
        self.bytes.extend(data);
114
776
115
776
        self.num_added += 1;
116
776
        self
117
776
    }
Unexecuted instantiation: _RINvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB3_11DataSection7segmentpEB7_
118
119
    /// Define an active data segment.
120
776
    pub fn active<D>(&mut self, memory_index: u32, offset: &ConstExpr, data: D) -> &mut Self
121
776
    where
122
776
        D: IntoIterator<Item = u8>,
123
776
        D::IntoIter: ExactSizeIterator,
124
776
    {
125
776
        self.segment(DataSegment {
126
776
            mode: DataSegmentMode::Active {
127
776
                memory_index,
128
776
                offset,
129
776
            },
130
776
            data,
131
776
        })
132
776
    }
_RINvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB3_11DataSection6activeINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1h_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
120
776
    pub fn active<D>(&mut self, memory_index: u32, offset: &ConstExpr, data: D) -> &mut Self
121
776
    where
122
776
        D: IntoIterator<Item = u8>,
123
776
        D::IntoIter: ExactSizeIterator,
124
776
    {
125
776
        self.segment(DataSegment {
126
776
            mode: DataSegmentMode::Active {
127
776
                memory_index,
128
776
                offset,
129
776
            },
130
776
            data,
131
776
        })
132
776
    }
Unexecuted instantiation: _RINvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB3_11DataSection6activepEB7_
133
134
    /// Define a passive data segment.
135
    ///
136
    /// Passive data segments are part of the bulk memory proposal.
137
0
    pub fn passive<D>(&mut self, data: D) -> &mut Self
138
0
    where
139
0
        D: IntoIterator<Item = u8>,
140
0
        D::IntoIter: ExactSizeIterator,
141
0
    {
142
0
        self.segment(DataSegment {
143
0
            mode: DataSegmentMode::Passive,
144
0
            data,
145
0
        })
146
0
    }
Unexecuted instantiation: _RINvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB3_11DataSection7passiveINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6copied6CopiedINtNtNtB1i_5slice4iter4IterhEEECs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RINvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB3_11DataSection7passivepEB7_
147
148
    /// Copy an already-encoded data segment into this data section.
149
0
    pub fn raw(&mut self, already_encoded_data_segment: &[u8]) -> &mut Self {
150
0
        self.bytes.extend_from_slice(already_encoded_data_segment);
151
0
        self.num_added += 1;
152
0
        self
153
0
    }
154
}
155
156
impl Encode for DataSection {
157
176
    fn encode(&self, sink: &mut Vec<u8>) {
158
176
        encode_section(sink, self.num_added, &self.bytes);
159
176
    }
160
}
161
162
impl Section for DataSection {
163
176
    fn id(&self) -> u8 {
164
176
        SectionId::Data.into()
165
176
    }
_RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB5_11DataSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
163
176
    fn id(&self) -> u8 {
164
176
        SectionId::Data.into()
165
176
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB5_11DataSectionNtB7_7Section2idB9_
166
}
167
168
/// An encoder for the data count section.
169
#[derive(Clone, Copy, Debug)]
170
pub struct DataCountSection {
171
    /// The number of segments in the data section.
172
    pub count: u32,
173
}
174
175
impl Encode for DataCountSection {
176
0
    fn encode(&self, sink: &mut Vec<u8>) {
177
0
        encoding_size(self.count).encode(sink);
178
0
        self.count.encode(sink);
179
0
    }
180
}
181
182
impl Section for DataCountSection {
183
0
    fn id(&self) -> u8 {
184
0
        SectionId::DataCount.into()
185
0
    }
Unexecuted instantiation: _RNvXs2_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB5_16DataCountSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs2_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4dataNtB5_16DataCountSectionNtB7_7Section2idB9_
186
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/dump.rs
Line
Count
Source (jump to first uncovered line)
1
use std::borrow::Cow;
2
3
use crate::{CustomSection, Encode, Section};
4
5
/// The "core" custom section for coredumps, as described in the
6
/// [tool-conventions
7
/// repository](https://github.com/WebAssembly/tool-conventions/blob/main/Coredump.md).
8
///
9
/// There are four sections that comprise a core dump:
10
///     - "core", which contains the name of the core dump
11
///     - "coremodules", a listing of modules
12
///     - "coreinstances", a listing of module instances
13
///     - "corestack", a listing of frames for a specific thread
14
///
15
/// # Example of how these could be constructed and encoded into a module:
16
///
17
/// ```
18
/// use wasm_encoder::{
19
///     CoreDumpInstancesSection, CoreDumpModulesSection, CoreDumpSection, CoreDumpStackSection,
20
///     CoreDumpValue, Module,
21
/// };
22
/// let core = CoreDumpSection::new("MyModule.wasm");
23
///
24
/// let mut modules = CoreDumpModulesSection::new();
25
/// modules.module("my_module");
26
///
27
/// let mut instances = CoreDumpInstancesSection::new();
28
/// let module_idx = 0;
29
/// let memories = vec![1];
30
/// let globals = vec![2];
31
/// instances.instance(module_idx, memories, globals);
32
///
33
/// let mut thread = CoreDumpStackSection::new("main");
34
/// let instance_index = 0;
35
/// let func_index = 42;
36
/// let code_offset = 0x1234;
37
/// let locals = vec![CoreDumpValue::I32(1)];
38
/// let stack = vec![CoreDumpValue::I32(2)];
39
/// thread.frame(instance_index, func_index, code_offset, locals, stack);
40
///
41
/// let mut module = Module::new();
42
/// module.section(&core);
43
/// module.section(&modules);
44
/// module.section(&instances);
45
/// module.section(&thread);
46
/// ```
47
#[derive(Clone, Debug, Default)]
48
pub struct CoreDumpSection {
49
    name: String,
50
}
51
52
impl CoreDumpSection {
53
    /// Create a new core dump section encoder
54
0
    pub fn new(name: impl Into<String>) -> Self {
55
0
        let name = name.into();
56
0
        CoreDumpSection { name }
57
0
    }
58
59
    /// View the encoded section as a CustomSection.
60
0
    fn as_custom<'a>(&'a self) -> CustomSection<'a> {
61
0
        let mut data = vec![0];
62
0
        self.name.encode(&mut data);
63
0
        CustomSection {
64
0
            name: "core".into(),
65
0
            data: Cow::Owned(data),
66
0
        }
67
0
    }
68
}
69
70
impl Encode for CoreDumpSection {
71
0
    fn encode(&self, sink: &mut Vec<u8>) {
72
0
        self.as_custom().encode(sink);
73
0
    }
74
}
75
76
impl Section for CoreDumpSection {
77
0
    fn id(&self) -> u8 {
78
0
        crate::core::SectionId::Custom as u8
79
0
    }
80
}
81
82
/// The "coremodules" custom section for coredumps which lists the names of the
83
/// modules
84
///
85
/// # Example
86
///
87
/// ```
88
/// use wasm_encoder::{CoreDumpModulesSection, Module};
89
/// let mut modules_section = CoreDumpModulesSection::new();
90
/// modules_section.module("my_module");
91
/// let mut module = Module::new();
92
/// module.section(&modules_section);
93
/// ```
94
#[derive(Debug)]
95
pub struct CoreDumpModulesSection {
96
    num_added: u32,
97
    bytes: Vec<u8>,
98
}
99
100
impl CoreDumpModulesSection {
101
    /// Create a new core dump modules section encoder.
102
0
    pub fn new() -> Self {
103
0
        CoreDumpModulesSection {
104
0
            bytes: vec![],
105
0
            num_added: 0,
106
0
        }
107
0
    }
108
109
    /// View the encoded section as a CustomSection.
110
0
    pub fn as_custom(&self) -> CustomSection<'_> {
111
0
        let mut data = vec![];
112
0
        self.num_added.encode(&mut data);
113
0
        data.extend(self.bytes.iter().copied());
114
0
        CustomSection {
115
0
            name: "coremodules".into(),
116
0
            data: Cow::Owned(data),
117
0
        }
118
0
    }
119
120
    /// Encode a module name into the section's bytes.
121
0
    pub fn module(&mut self, module_name: impl AsRef<str>) -> &mut Self {
122
0
        self.bytes.push(0x0);
123
0
        module_name.as_ref().encode(&mut self.bytes);
124
0
        self.num_added += 1;
125
0
        self
126
0
    }
127
128
    /// The number of modules that are encoded in the section.
129
0
    pub fn len(&self) -> u32 {
130
0
        self.num_added
131
0
    }
132
}
133
134
impl Encode for CoreDumpModulesSection {
135
0
    fn encode(&self, sink: &mut Vec<u8>) {
136
0
        self.as_custom().encode(sink);
137
0
    }
138
}
139
140
impl Section for CoreDumpModulesSection {
141
0
    fn id(&self) -> u8 {
142
0
        crate::core::SectionId::Custom as u8
143
0
    }
144
}
145
146
/// The "coreinstances" section for the core dump
147
#[derive(Debug)]
148
pub struct CoreDumpInstancesSection {
149
    num_added: u32,
150
    bytes: Vec<u8>,
151
}
152
153
impl CoreDumpInstancesSection {
154
    /// Create a new core dump instances section encoder.
155
0
    pub fn new() -> Self {
156
0
        CoreDumpInstancesSection {
157
0
            bytes: vec![],
158
0
            num_added: 0,
159
0
        }
160
0
    }
161
162
    /// View the encoded section as a CustomSection.
163
0
    pub fn as_custom(&self) -> CustomSection<'_> {
164
0
        let mut data = vec![];
165
0
        self.num_added.encode(&mut data);
166
0
        data.extend(self.bytes.iter().copied());
167
0
        CustomSection {
168
0
            name: "coreinstances".into(),
169
0
            data: Cow::Owned(data),
170
0
        }
171
0
    }
172
173
    /// Encode an instance into the section's bytes.
174
0
    pub fn instance<M, G>(&mut self, module_index: u32, memories: M, globals: G) -> &mut Self
175
0
    where
176
0
        M: IntoIterator<Item = u32>,
177
0
        <M as IntoIterator>::IntoIter: ExactSizeIterator,
178
0
        G: IntoIterator<Item = u32>,
179
0
        <G as IntoIterator>::IntoIter: ExactSizeIterator,
180
0
    {
181
0
        self.bytes.push(0x0);
182
0
        module_index.encode(&mut self.bytes);
183
0
        crate::encode_vec(memories, &mut self.bytes);
184
0
        crate::encode_vec(globals, &mut self.bytes);
185
0
        self.num_added += 1;
186
0
        self
187
0
    }
188
189
    /// The number of modules that are encoded in the section.
190
0
    pub fn len(&self) -> u32 {
191
0
        self.num_added
192
0
    }
193
}
194
195
impl Encode for CoreDumpInstancesSection {
196
0
    fn encode(&self, sink: &mut Vec<u8>) {
197
0
        self.as_custom().encode(sink);
198
0
    }
199
}
200
201
impl Section for CoreDumpInstancesSection {
202
0
    fn id(&self) -> u8 {
203
0
        crate::core::SectionId::Custom as u8
204
0
    }
205
}
206
207
/// A "corestack" custom section as described in the [tool-conventions
208
/// repository](https://github.com/WebAssembly/tool-conventions/blob/main/Coredump.md)
209
///
210
/// # Example
211
///
212
/// ```
213
/// use wasm_encoder::{CoreDumpStackSection, Module, CoreDumpValue};
214
/// let mut thread = CoreDumpStackSection::new("main");
215
///
216
/// let instance_index = 0;
217
/// let func_index = 42;
218
/// let code_offset = 0x1234;
219
/// let locals = vec![CoreDumpValue::I32(1)];
220
/// let stack = vec![CoreDumpValue::I32(2)];
221
/// thread.frame(instance_index, func_index, code_offset, locals, stack);
222
///
223
/// let mut module = Module::new();
224
/// module.section(&thread);
225
/// ```
226
#[derive(Clone, Debug, Default)]
227
pub struct CoreDumpStackSection {
228
    frame_bytes: Vec<u8>,
229
    count: u32,
230
    name: String,
231
}
232
233
impl CoreDumpStackSection {
234
    /// Create a new core dump stack section encoder.
235
0
    pub fn new(name: impl Into<String>) -> Self {
236
0
        let name = name.into();
237
0
        CoreDumpStackSection {
238
0
            frame_bytes: Vec::new(),
239
0
            count: 0,
240
0
            name,
241
0
        }
242
0
    }
243
244
    /// Add a stack frame to this coredump stack section.
245
0
    pub fn frame<L, S>(
246
0
        &mut self,
247
0
        instanceidx: u32,
248
0
        funcidx: u32,
249
0
        codeoffset: u32,
250
0
        locals: L,
251
0
        stack: S,
252
0
    ) -> &mut Self
253
0
    where
254
0
        L: IntoIterator<Item = CoreDumpValue>,
255
0
        <L as IntoIterator>::IntoIter: ExactSizeIterator,
256
0
        S: IntoIterator<Item = CoreDumpValue>,
257
0
        <S as IntoIterator>::IntoIter: ExactSizeIterator,
258
0
    {
259
0
        self.count += 1;
260
0
        self.frame_bytes.push(0);
261
0
        instanceidx.encode(&mut self.frame_bytes);
262
0
        funcidx.encode(&mut self.frame_bytes);
263
0
        codeoffset.encode(&mut self.frame_bytes);
264
0
        crate::encode_vec(locals, &mut self.frame_bytes);
265
0
        crate::encode_vec(stack, &mut self.frame_bytes);
266
0
        self
267
0
    }
268
269
    /// View the encoded section as a CustomSection.
270
0
    pub fn as_custom<'a>(&'a self) -> CustomSection<'a> {
271
0
        let mut data = vec![0];
272
0
        self.name.encode(&mut data);
273
0
        self.count.encode(&mut data);
274
0
        data.extend(&self.frame_bytes);
275
0
        CustomSection {
276
0
            name: "corestack".into(),
277
0
            data: Cow::Owned(data),
278
0
        }
279
0
    }
280
}
281
282
impl Encode for CoreDumpStackSection {
283
0
    fn encode(&self, sink: &mut Vec<u8>) {
284
0
        self.as_custom().encode(sink);
285
0
    }
286
}
287
288
impl Section for CoreDumpStackSection {
289
0
    fn id(&self) -> u8 {
290
0
        crate::core::SectionId::Custom as u8
291
0
    }
292
}
293
294
/// Local and stack values are encoded using one byte for the type (similar to
295
/// Wasm's Number Types) followed by bytes representing the actual value
296
/// See the tool-conventions repo for more details.
297
#[derive(Clone, Debug)]
298
pub enum CoreDumpValue {
299
    /// a missing value (usually missing because it was optimized out)
300
    Missing,
301
    /// An i32 value
302
    I32(i32),
303
    /// An i64 value
304
    I64(i64),
305
    /// An f32 value
306
    F32(f32),
307
    /// An f64 value
308
    F64(f64),
309
}
310
311
impl Encode for CoreDumpValue {
312
0
    fn encode(&self, sink: &mut Vec<u8>) {
313
0
        match self {
314
0
            CoreDumpValue::Missing => sink.push(0x01),
315
0
            CoreDumpValue::I32(x) => {
316
0
                sink.push(0x7F);
317
0
                x.encode(sink);
318
0
            }
319
0
            CoreDumpValue::I64(x) => {
320
0
                sink.push(0x7E);
321
0
                x.encode(sink);
322
0
            }
323
0
            CoreDumpValue::F32(x) => {
324
0
                sink.push(0x7D);
325
0
                x.encode(sink);
326
0
            }
327
0
            CoreDumpValue::F64(x) => {
328
0
                sink.push(0x7C);
329
0
                x.encode(sink);
330
0
            }
331
        }
332
0
    }
333
}
334
335
#[cfg(test)]
336
mod tests {
337
    use super::*;
338
    use crate::Module;
339
    use wasmparser::{KnownCustom, Parser, Payload};
340
341
    // Create new core dump section and test whether it is properly encoded and
342
    // parsed back out by wasmparser
343
    #[test]
344
    fn test_roundtrip_core() {
345
        let core = CoreDumpSection::new("test.wasm");
346
        let mut module = Module::new();
347
        module.section(&core);
348
349
        let wasm_bytes = module.finish();
350
351
        let mut parser = Parser::new(0).parse_all(&wasm_bytes);
352
        match parser.next() {
353
            Some(Ok(Payload::Version { .. })) => {}
354
            _ => panic!(""),
355
        }
356
357
        let payload = parser
358
            .next()
359
            .expect("parser is not empty")
360
            .expect("element is a payload");
361
        match payload {
362
            Payload::CustomSection(section) => {
363
                assert_eq!(section.name(), "core");
364
                let core = match section.as_known() {
365
                    KnownCustom::CoreDump(s) => s,
366
                    _ => panic!("not coredump"),
367
                };
368
                assert_eq!(core.name, "test.wasm");
369
            }
370
            _ => panic!("unexpected payload"),
371
        }
372
    }
373
374
    #[test]
375
    fn test_roundtrip_coremodules() {
376
        let mut coremodules = CoreDumpModulesSection::new();
377
        coremodules.module("test_module");
378
379
        let mut module = crate::Module::new();
380
        module.section(&coremodules);
381
382
        let wasm_bytes = module.finish();
383
384
        let mut parser = Parser::new(0).parse_all(&wasm_bytes);
385
        match parser.next() {
386
            Some(Ok(Payload::Version { .. })) => {}
387
            _ => panic!(""),
388
        }
389
390
        let payload = parser
391
            .next()
392
            .expect("parser is not empty")
393
            .expect("element is a payload");
394
        match payload {
395
            Payload::CustomSection(section) => {
396
                assert_eq!(section.name(), "coremodules");
397
                let modules = match section.as_known() {
398
                    KnownCustom::CoreDumpModules(s) => s,
399
                    _ => panic!("not coremodules"),
400
                };
401
                assert_eq!(modules.modules[0], "test_module");
402
            }
403
            _ => panic!("unexpected payload"),
404
        }
405
    }
406
407
    #[test]
408
    fn test_roundtrip_coreinstances() {
409
        let mut coreinstances = CoreDumpInstancesSection::new();
410
        let module_index = 0;
411
        let memories = vec![42];
412
        let globals = vec![17];
413
        coreinstances.instance(module_index, memories, globals);
414
415
        let mut module = Module::new();
416
        module.section(&coreinstances);
417
        let wasm_bytes = module.finish();
418
419
        let mut parser = Parser::new(0).parse_all(&wasm_bytes);
420
        match parser.next() {
421
            Some(Ok(Payload::Version { .. })) => {}
422
            _ => panic!(""),
423
        }
424
425
        let payload = parser
426
            .next()
427
            .expect("parser is not empty")
428
            .expect("element is a payload");
429
        match payload {
430
            Payload::CustomSection(section) => {
431
                assert_eq!(section.name(), "coreinstances");
432
                let coreinstances = match section.as_known() {
433
                    KnownCustom::CoreDumpInstances(s) => s,
434
                    _ => panic!("not coreinstances"),
435
                };
436
                assert_eq!(coreinstances.instances.len(), 1);
437
                let instance = coreinstances
438
                    .instances
439
                    .first()
440
                    .expect("instance is encoded");
441
                assert_eq!(instance.module_index, 0);
442
                assert_eq!(instance.memories.len(), 1);
443
                assert_eq!(instance.globals.len(), 1);
444
            }
445
            _ => panic!("unexpected payload"),
446
        }
447
    }
448
449
    // Create new corestack section and test whether it is properly encoded and
450
    // parsed back out by wasmparser
451
    #[test]
452
    fn test_roundtrip_corestack() {
453
        let mut corestack = CoreDumpStackSection::new("main");
454
        corestack.frame(
455
            0,
456
            12,
457
            0,
458
            vec![CoreDumpValue::I32(10)],
459
            vec![CoreDumpValue::I32(42)],
460
        );
461
        let mut module = Module::new();
462
        module.section(&corestack);
463
        let wasm_bytes = module.finish();
464
465
        let mut parser = Parser::new(0).parse_all(&wasm_bytes);
466
        match parser.next() {
467
            Some(Ok(Payload::Version { .. })) => {}
468
            _ => panic!(""),
469
        }
470
471
        let payload = parser
472
            .next()
473
            .expect("parser is not empty")
474
            .expect("element is a payload");
475
        match payload {
476
            Payload::CustomSection(section) => {
477
                assert_eq!(section.name(), "corestack");
478
                let corestack = match section.as_known() {
479
                    KnownCustom::CoreDumpStack(s) => s,
480
                    _ => panic!("not a corestack section"),
481
                };
482
                assert_eq!(corestack.name, "main");
483
                assert_eq!(corestack.frames.len(), 1);
484
                let frame = corestack
485
                    .frames
486
                    .first()
487
                    .expect("frame is encoded in corestack");
488
                assert_eq!(frame.instanceidx, 0);
489
                assert_eq!(frame.funcidx, 12);
490
                assert_eq!(frame.codeoffset, 0);
491
                assert_eq!(frame.locals.len(), 1);
492
                match frame.locals.first().expect("frame contains a local") {
493
                    &wasmparser::CoreDumpValue::I32(val) => assert_eq!(val, 10),
494
                    _ => panic!("unexpected local value"),
495
                }
496
                assert_eq!(frame.stack.len(), 1);
497
                match frame.stack.first().expect("stack contains a value") {
498
                    &wasmparser::CoreDumpValue::I32(val) => assert_eq!(val, 42),
499
                    _ => panic!("unexpected stack value"),
500
                }
501
            }
502
            _ => panic!("unexpected payload"),
503
        }
504
    }
505
506
    #[test]
507
    fn test_encode_coredump_section() {
508
        let core = CoreDumpSection::new("test");
509
510
        let mut encoded = vec![];
511
        core.encode(&mut encoded);
512
513
        #[rustfmt::skip]
514
        assert_eq!(encoded, vec![
515
            // section length
516
            11,
517
            // name length
518
            4,
519
            // section name (core)
520
            b'c',b'o',b'r',b'e',
521
            // process-info (0, data length, data)
522
            0, 4, b't', b'e', b's', b't',
523
        ]);
524
    }
525
526
    #[test]
527
    fn test_encode_coremodules_section() {
528
        let mut modules = CoreDumpModulesSection::new();
529
        modules.module("mod1");
530
        modules.module("mod2");
531
532
        let mut encoded = vec![];
533
        modules.encode(&mut encoded);
534
535
        #[rustfmt::skip]
536
        assert_eq!(encoded, vec![
537
            // section length
538
            25,
539
            // name length
540
            11,
541
            // section name (coremodules)
542
            b'c',b'o',b'r',b'e',b'm',b'o',b'd',b'u',b'l',b'e',b's',
543
            // module count
544
            2,
545
            // 0x0, name-length, module name (mod1)
546
            0x0, 4, b'm',b'o',b'd',b'1',
547
            // 0x0, name-length, module name (mod2)
548
            0x0, 4, b'm',b'o',b'd',b'2'
549
        ]);
550
    }
551
552
    #[test]
553
    fn test_encode_coreinstances_section() {
554
        let mut instances = CoreDumpInstancesSection::new();
555
        instances.instance(0, vec![42], vec![17]);
556
557
        let mut encoded = vec![];
558
        instances.encode(&mut encoded);
559
560
        #[rustfmt::skip]
561
        assert_eq!(encoded, vec![
562
            // section length
563
            21,
564
            // name length
565
            13,
566
            // section name (coreinstances)
567
            b'c',b'o',b'r',b'e',b'i',b'n',b's',b't',b'a',b'n',b'c',b'e',b's',
568
            // instance count
569
            1,
570
            // 0x0, module_idx
571
            0x0, 0,
572
            // memories count, memories
573
            1, 42,
574
            // globals count, globals
575
            1, 17
576
        ]);
577
    }
578
579
    #[test]
580
    fn test_encode_corestack_section() {
581
        let mut thread = CoreDumpStackSection::new("main");
582
        thread.frame(
583
            0,
584
            42,
585
            51,
586
            vec![CoreDumpValue::I32(1)],
587
            vec![CoreDumpValue::I32(2)],
588
        );
589
590
        let mut encoded = vec![];
591
        thread.encode(&mut encoded);
592
593
        #[rustfmt::skip]
594
        assert_eq!(
595
            encoded,
596
            vec![
597
                // section length
598
                27,
599
                // length of name.
600
                9,
601
                // section name (corestack)
602
                b'c',b'o',b'r',b'e',b's',b't',b'a',b'c',b'k',
603
                // 0x0, thread name length
604
                0, 4,
605
                // thread name (main)
606
                b'm',b'a',b'i',b'n',
607
                // frame count
608
                1,
609
                // 0x0, instanceidx, funcidx, codeoffset
610
                0, 0, 42, 51,
611
                // local count
612
                1,
613
                // local value type
614
                0x7F,
615
                // local value
616
                1,
617
                // stack count
618
                1,
619
                // stack value type
620
                0x7F,
621
                // stack value
622
                2
623
624
            ]
625
        );
626
    }
627
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/elements.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, ConstExpr, Encode, RefType, Section, SectionId};
2
3
/// An encoder for the element section.
4
///
5
/// Element sections are only supported for modules.
6
///
7
/// # Example
8
///
9
/// ```
10
/// use wasm_encoder::{
11
///     Elements, ElementSection, Module, TableSection, TableType,
12
///     RefType, ConstExpr
13
/// };
14
///
15
/// let mut tables = TableSection::new();
16
/// tables.table(TableType {
17
///     element_type: RefType::FUNCREF,
18
///     minimum: 128,
19
///     maximum: None,
20
///     table64: false,
21
/// });
22
///
23
/// let mut elements = ElementSection::new();
24
/// let table_index = 0;
25
/// let offset = ConstExpr::i32_const(42);
26
/// let functions = Elements::Functions(&[
27
///     // Function indices...
28
/// ]);
29
/// elements.active(Some(table_index), &offset, functions);
30
///
31
/// let mut module = Module::new();
32
/// module
33
///     .section(&tables)
34
///     .section(&elements);
35
///
36
/// let wasm_bytes = module.finish();
37
/// ```
38
#[derive(Clone, Default, Debug)]
39
pub struct ElementSection {
40
    bytes: Vec<u8>,
41
    num_added: u32,
42
}
43
44
/// A sequence of elements in a segment in the element section.
45
#[derive(Clone, Copy, Debug)]
46
pub enum Elements<'a> {
47
    /// A sequences of references to functions by their indices.
48
    Functions(&'a [u32]),
49
    /// A sequence of reference expressions.
50
    Expressions(RefType, &'a [ConstExpr]),
51
}
52
53
/// An element segment's mode.
54
#[derive(Clone, Debug)]
55
pub enum ElementMode<'a> {
56
    /// A passive element segment.
57
    ///
58
    /// Passive segments are part of the bulk memory proposal.
59
    Passive,
60
    /// A declared element segment.
61
    ///
62
    /// Declared segments are part of the bulk memory proposal.
63
    Declared,
64
    /// An active element segment.
65
    Active {
66
        /// The table index.
67
        ///
68
        /// `Active` element specifying a `None` table forces the MVP encoding and refers to the
69
        /// 0th table holding `funcref`s. Non-`None` tables use the encoding introduced with the
70
        /// bulk memory proposal and can refer to tables with any valid reference type.
71
        table: Option<u32>,
72
        /// The offset within the table to place this segment.
73
        offset: &'a ConstExpr,
74
    },
75
}
76
77
/// An element segment in the element section.
78
#[derive(Clone, Debug)]
79
pub struct ElementSegment<'a> {
80
    /// The element segment's mode.
81
    pub mode: ElementMode<'a>,
82
    /// This segment's elements.
83
    pub elements: Elements<'a>,
84
}
85
86
impl ElementSection {
87
    /// Create a new element section encoder.
88
252
    pub fn new() -> Self {
89
252
        Self::default()
90
252
    }
_RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core8elementsNtB2_14ElementSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
88
252
    pub fn new() -> Self {
89
252
        Self::default()
90
252
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core8elementsNtB2_14ElementSection3newB6_
91
92
    /// The number of element segments in the section.
93
0
    pub fn len(&self) -> u32 {
94
0
        self.num_added
95
0
    }
96
97
    /// Determines if the section is empty.
98
0
    pub fn is_empty(&self) -> bool {
99
0
        self.num_added == 0
100
0
    }
101
102
    /// Define an element segment.
103
1.58k
    pub fn segment<'a>(&mut self, segment: ElementSegment<'a>) -> &mut Self {
104
1.58k
        let expr_bit = match segment.elements {
105
0
            Elements::Expressions(..) => 0b100u32,
106
1.58k
            Elements::Functions(_) => 0b000u32,
107
        };
108
1.58k
        let mut encode_type = false;
109
1.58k
        match &segment.mode {
110
0
            ElementMode::Passive => {
111
0
                (0x01 | expr_bit).encode(&mut self.bytes);
112
0
                encode_type = true;
113
0
            }
114
1.58k
            ElementMode::Active { table, offset } => {
115
1.58k
                match (table, &segment.elements) {
116
                    // If the `table` is not specified then the 0x00 encoding
117
                    // can be used with either function indices or expressions
118
                    // that have a `funcref` type.
119
1.58k
                    (None, Elements::Functions(_) | Elements::Expressions(RefType::FUNCREF, _)) => {
120
1.58k
                        (/* 0x00 | */expr_bit).encode(&mut self.bytes);
121
1.58k
                    }
122
123
                    // ... otherwise fall through for all other expressions here
124
                    // with table 0 or an explicitly specified table to the 0x02
125
                    // encoding.
126
0
                    (None, Elements::Expressions(..)) | (Some(_), _) => {
127
0
                        (0x02 | expr_bit).encode(&mut self.bytes);
128
0
                        table.unwrap_or(0).encode(&mut self.bytes);
129
0
                        encode_type = true;
130
0
                    }
131
                }
132
1.58k
                offset.encode(&mut self.bytes);
133
            }
134
0
            ElementMode::Declared => {
135
0
                (0x03 | expr_bit).encode(&mut self.bytes);
136
0
                encode_type = true;
137
0
            }
138
        }
139
140
1.58k
        match segment.elements {
141
1.58k
            Elements::Functions(fs) => {
142
1.58k
                if encode_type {
143
0
                    // elemkind == funcref
144
0
                    self.bytes.push(0x00);
145
1.58k
                }
146
1.58k
                fs.encode(&mut self.bytes);
147
            }
148
0
            Elements::Expressions(ty, e) => {
149
0
                if encode_type {
150
0
                    ty.encode(&mut self.bytes);
151
0
                }
152
0
                e.len().encode(&mut self.bytes);
153
0
                for expr in e {
154
0
                    expr.encode(&mut self.bytes);
155
0
                }
156
            }
157
        }
158
159
1.58k
        self.num_added += 1;
160
1.58k
        self
161
1.58k
    }
162
163
    /// Define an active element segment.
164
    ///
165
    /// `Active` element specifying a `None` table forces the MVP encoding and refers to the 0th
166
    /// table holding `funcref`s. Non-`None` tables use the encoding introduced with the bulk
167
    /// memory proposal and can refer to tables with any valid reference type.
168
1.58k
    pub fn active(
169
1.58k
        &mut self,
170
1.58k
        table_index: Option<u32>,
171
1.58k
        offset: &ConstExpr,
172
1.58k
        elements: Elements<'_>,
173
1.58k
    ) -> &mut Self {
174
1.58k
        self.segment(ElementSegment {
175
1.58k
            mode: ElementMode::Active {
176
1.58k
                table: table_index,
177
1.58k
                offset,
178
1.58k
            },
179
1.58k
            elements,
180
1.58k
        })
181
1.58k
    }
182
183
    /// Encode a passive element segment.
184
    ///
185
    /// Passive segments are part of the bulk memory proposal.
186
0
    pub fn passive<'a>(&mut self, elements: Elements<'a>) -> &mut Self {
187
0
        self.segment(ElementSegment {
188
0
            mode: ElementMode::Passive,
189
0
            elements,
190
0
        })
191
0
    }
192
193
    /// Encode a declared element segment.
194
    ///
195
    /// Declared segments are part of the bulk memory proposal.
196
0
    pub fn declared<'a>(&mut self, elements: Elements<'a>) -> &mut Self {
197
0
        self.segment(ElementSegment {
198
0
            mode: ElementMode::Declared,
199
0
            elements,
200
0
        })
201
0
    }
202
203
    /// Copy a raw, already-encoded element segment into this elements section.
204
0
    pub fn raw(&mut self, raw_bytes: &[u8]) -> &mut Self {
205
0
        self.bytes.extend_from_slice(raw_bytes);
206
0
        self.num_added += 1;
207
0
        self
208
0
    }
209
}
210
211
impl Encode for ElementSection {
212
252
    fn encode(&self, sink: &mut Vec<u8>) {
213
252
        encode_section(sink, self.num_added, &self.bytes);
214
252
    }
215
}
216
217
impl Section for ElementSection {
218
252
    fn id(&self) -> u8 {
219
252
        SectionId::Element.into()
220
252
    }
_RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core8elementsNtB5_14ElementSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
218
252
    fn id(&self) -> u8 {
219
252
        SectionId::Element.into()
220
252
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core8elementsNtB5_14ElementSectionNtB7_7Section2idB9_
221
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/exports.rs
Line
Count
Source (jump to first uncovered line)
1
use super::{
2
    CORE_FUNCTION_SORT, CORE_GLOBAL_SORT, CORE_MEMORY_SORT, CORE_TABLE_SORT, CORE_TAG_SORT,
3
};
4
use crate::{encode_section, Encode, Section, SectionId};
5
6
/// Represents the kind of an export from a WebAssembly module.
7
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
8
#[repr(u8)]
9
pub enum ExportKind {
10
    /// The export is a function.
11
    Func = CORE_FUNCTION_SORT,
12
    /// The export is a table.
13
    Table = CORE_TABLE_SORT,
14
    /// The export is a memory.
15
    Memory = CORE_MEMORY_SORT,
16
    /// The export is a global.
17
    Global = CORE_GLOBAL_SORT,
18
    /// The export is a tag.
19
    Tag = CORE_TAG_SORT,
20
}
21
22
impl Encode for ExportKind {
23
5.46k
    fn encode(&self, sink: &mut Vec<u8>) {
24
5.46k
        sink.push(*self as u8);
25
5.46k
    }
26
}
27
28
#[cfg(feature = "wasmparser")]
29
impl From<wasmparser::ExternalKind> for ExportKind {
30
    fn from(external_kind: wasmparser::ExternalKind) -> Self {
31
        match external_kind {
32
            wasmparser::ExternalKind::Func => ExportKind::Func,
33
            wasmparser::ExternalKind::Table => ExportKind::Table,
34
            wasmparser::ExternalKind::Memory => ExportKind::Memory,
35
            wasmparser::ExternalKind::Global => ExportKind::Global,
36
            wasmparser::ExternalKind::Tag => ExportKind::Tag,
37
        }
38
    }
39
}
40
41
/// An encoder for the export section of WebAssembly module.
42
///
43
/// # Example
44
///
45
/// ```rust
46
/// use wasm_encoder::{Module, ExportSection, ExportKind};
47
///
48
/// let mut exports = ExportSection::new();
49
/// exports.export("foo", ExportKind::Func, 0);
50
///
51
/// let mut module = Module::new();
52
/// module.section(&exports);
53
///
54
/// let bytes = module.finish();
55
/// ```
56
#[derive(Clone, Debug, Default)]
57
pub struct ExportSection {
58
    bytes: Vec<u8>,
59
    num_added: u32,
60
}
61
62
impl ExportSection {
63
    /// Create a new export section encoder.
64
897
    pub fn new() -> Self {
65
897
        Self::default()
66
897
    }
_RNvMs_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7exportsNtB4_13ExportSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
64
897
    pub fn new() -> Self {
65
897
        Self::default()
66
897
    }
Unexecuted instantiation: _RNvMs_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7exportsNtB4_13ExportSection3newB8_
67
68
    /// The number of exports in the section.
69
0
    pub fn len(&self) -> u32 {
70
0
        self.num_added
71
0
    }
72
73
    /// Determines if the section is empty.
74
0
    pub fn is_empty(&self) -> bool {
75
0
        self.num_added == 0
76
0
    }
77
78
    /// Define an export in the export section.
79
5.46k
    pub fn export(&mut self, name: &str, kind: ExportKind, index: u32) -> &mut Self {
80
5.46k
        name.encode(&mut self.bytes);
81
5.46k
        kind.encode(&mut self.bytes);
82
5.46k
        index.encode(&mut self.bytes);
83
5.46k
        self.num_added += 1;
84
5.46k
        self
85
5.46k
    }
86
}
87
88
impl Encode for ExportSection {
89
897
    fn encode(&self, sink: &mut Vec<u8>) {
90
897
        encode_section(sink, self.num_added, &self.bytes);
91
897
    }
92
}
93
94
impl Section for ExportSection {
95
897
    fn id(&self) -> u8 {
96
897
        SectionId::Export.into()
97
897
    }
_RNvXs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7exportsNtB5_13ExportSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
95
897
    fn id(&self) -> u8 {
96
897
        SectionId::Export.into()
97
897
    }
Unexecuted instantiation: _RNvXs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7exportsNtB5_13ExportSectionNtB7_7Section2idB9_
98
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/functions.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, Encode, Section, SectionId};
2
3
/// An encoder for the function section of WebAssembly modules.
4
///
5
/// # Example
6
///
7
/// ```
8
/// use wasm_encoder::{Module, FunctionSection, ValType};
9
///
10
/// let mut functions = FunctionSection::new();
11
/// let type_index = 0;
12
/// functions.function(type_index);
13
///
14
/// let mut module = Module::new();
15
/// module.section(&functions);
16
///
17
/// // Note: this will generate an invalid module because we didn't generate a
18
/// // code section containing the function body. See the documentation for
19
/// // `CodeSection` for details.
20
///
21
/// let bytes = module.finish();
22
/// ```
23
#[derive(Clone, Debug, Default)]
24
pub struct FunctionSection {
25
    bytes: Vec<u8>,
26
    num_added: u32,
27
}
28
29
impl FunctionSection {
30
    /// Construct a new module function section encoder.
31
4.09k
    pub fn new() -> Self {
32
4.09k
        Self::default()
33
4.09k
    }
_RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core9functionsNtB2_15FunctionSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
31
4.09k
    pub fn new() -> Self {
32
4.09k
        Self::default()
33
4.09k
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core9functionsNtB2_15FunctionSection3newB6_
34
35
    /// The number of functions in the section.
36
0
    pub fn len(&self) -> u32 {
37
0
        self.num_added
38
0
    }
39
40
    /// Determines if the section is empty.
41
0
    pub fn is_empty(&self) -> bool {
42
0
        self.num_added == 0
43
0
    }
44
45
    /// Define a function in a module's function section.
46
15.8k
    pub fn function(&mut self, type_index: u32) -> &mut Self {
47
15.8k
        type_index.encode(&mut self.bytes);
48
15.8k
        self.num_added += 1;
49
15.8k
        self
50
15.8k
    }
51
}
52
53
impl Encode for FunctionSection {
54
4.09k
    fn encode(&self, sink: &mut Vec<u8>) {
55
4.09k
        encode_section(sink, self.num_added, &self.bytes);
56
4.09k
    }
57
}
58
59
impl Section for FunctionSection {
60
4.09k
    fn id(&self) -> u8 {
61
4.09k
        SectionId::Function.into()
62
4.09k
    }
_RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core9functionsNtB5_15FunctionSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
60
4.09k
    fn id(&self) -> u8 {
61
4.09k
        SectionId::Function.into()
62
4.09k
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core9functionsNtB5_15FunctionSectionNtB7_7Section2idB9_
63
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/globals.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, ConstExpr, Encode, Section, SectionId, ValType};
2
3
/// An encoder for the global section.
4
///
5
/// Global sections are only supported for modules.
6
///
7
/// # Example
8
///
9
/// ```
10
/// use wasm_encoder::{ConstExpr, Module, GlobalSection, GlobalType, Instruction, ValType};
11
///
12
/// let mut globals = GlobalSection::new();
13
/// globals.global(
14
///     GlobalType {
15
///         val_type: ValType::I32,
16
///         mutable: false,
17
///         shared: false,
18
///     },
19
///     &ConstExpr::i32_const(42),
20
/// );
21
///
22
/// let mut module = Module::new();
23
/// module.section(&globals);
24
///
25
/// let wasm_bytes = module.finish();
26
/// ```
27
#[derive(Clone, Default, Debug)]
28
pub struct GlobalSection {
29
    bytes: Vec<u8>,
30
    num_added: u32,
31
}
32
33
impl GlobalSection {
34
    /// Create a new global section encoder.
35
1.67k
    pub fn new() -> Self {
36
1.67k
        Self::default()
37
1.67k
    }
_RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core7globalsNtB2_13GlobalSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
35
1.67k
    pub fn new() -> Self {
36
1.67k
        Self::default()
37
1.67k
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core7globalsNtB2_13GlobalSection3newB6_
38
39
    /// The number of globals in the section.
40
0
    pub fn len(&self) -> u32 {
41
0
        self.num_added
42
0
    }
43
44
    /// Determines if the section is empty.
45
0
    pub fn is_empty(&self) -> bool {
46
0
        self.num_added == 0
47
0
    }
48
49
    /// Define a global.
50
3.51k
    pub fn global(&mut self, global_type: GlobalType, init_expr: &ConstExpr) -> &mut Self {
51
3.51k
        global_type.encode(&mut self.bytes);
52
3.51k
        init_expr.encode(&mut self.bytes);
53
3.51k
        self.num_added += 1;
54
3.51k
        self
55
3.51k
    }
56
57
    /// Add a raw byte slice into this code section as a global.
58
0
    pub fn raw(&mut self, data: &[u8]) -> &mut Self {
59
0
        self.bytes.extend(data);
60
0
        self.num_added += 1;
61
0
        self
62
0
    }
63
}
64
65
impl Encode for GlobalSection {
66
1.67k
    fn encode(&self, sink: &mut Vec<u8>) {
67
1.67k
        encode_section(sink, self.num_added, &self.bytes);
68
1.67k
    }
69
}
70
71
impl Section for GlobalSection {
72
1.67k
    fn id(&self) -> u8 {
73
1.67k
        SectionId::Global.into()
74
1.67k
    }
_RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7globalsNtB5_13GlobalSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
72
1.67k
    fn id(&self) -> u8 {
73
1.67k
        SectionId::Global.into()
74
1.67k
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7globalsNtB5_13GlobalSectionNtB7_7Section2idB9_
75
}
76
77
/// A global's type.
78
#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash)]
79
pub struct GlobalType {
80
    /// This global's value type.
81
    pub val_type: ValType,
82
    /// Whether this global is mutable or not.
83
    pub mutable: bool,
84
    /// Whether this global is shared or not.
85
    pub shared: bool,
86
}
87
88
impl Encode for GlobalType {
89
5.65k
    fn encode(&self, sink: &mut Vec<u8>) {
90
5.65k
        self.val_type.encode(sink);
91
5.65k
        let mut flag = 0;
92
5.65k
        if self.mutable {
93
4.25k
            flag |= 0b01;
94
4.25k
        }
95
5.65k
        if self.shared {
96
0
            flag |= 0b10;
97
5.65k
        }
98
5.65k
        sink.push(flag);
99
5.65k
    }
100
}
101
102
#[cfg(feature = "wasmparser")]
103
impl TryFrom<wasmparser::GlobalType> for GlobalType {
104
    type Error = ();
105
    fn try_from(global_ty: wasmparser::GlobalType) -> Result<Self, Self::Error> {
106
        Ok(GlobalType {
107
            val_type: global_ty.content_type.try_into()?,
108
            mutable: global_ty.mutable,
109
            shared: global_ty.shared,
110
        })
111
    }
112
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/imports.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{
2
    encode_section, Encode, GlobalType, MemoryType, Section, SectionId, TableType, TagType,
3
    CORE_FUNCTION_SORT, CORE_GLOBAL_SORT, CORE_MEMORY_SORT, CORE_TABLE_SORT, CORE_TAG_SORT,
4
};
5
6
/// The type of an entity.
7
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8
pub enum EntityType {
9
    /// A function type.
10
    ///
11
    /// The value is an index into the types section.
12
    Function(u32),
13
    /// A table type.
14
    Table(TableType),
15
    /// A memory type.
16
    Memory(MemoryType),
17
    /// A global type.
18
    Global(GlobalType),
19
    /// A tag type.
20
    ///
21
    /// This variant is used with the exception handling proposal.
22
    Tag(TagType),
23
}
24
25
impl Encode for EntityType {
26
4.32k
    fn encode(&self, sink: &mut Vec<u8>) {
27
4.32k
        match self {
28
1.56k
            Self::Function(i) => {
29
1.56k
                sink.push(CORE_FUNCTION_SORT);
30
1.56k
                i.encode(sink);
31
1.56k
            }
32
288
            Self::Table(t) => {
33
288
                sink.push(CORE_TABLE_SORT);
34
288
                t.encode(sink);
35
288
            }
36
336
            Self::Memory(t) => {
37
336
                sink.push(CORE_MEMORY_SORT);
38
336
                t.encode(sink);
39
336
            }
40
2.13k
            Self::Global(t) => {
41
2.13k
                sink.push(CORE_GLOBAL_SORT);
42
2.13k
                t.encode(sink);
43
2.13k
            }
44
0
            Self::Tag(t) => {
45
0
                sink.push(CORE_TAG_SORT);
46
0
                t.encode(sink);
47
0
            }
48
        }
49
4.32k
    }
50
}
51
52
impl From<TableType> for EntityType {
53
288
    fn from(t: TableType) -> Self {
54
288
        Self::Table(t)
55
288
    }
_RNvXs_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB4_10EntityTypeINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtB6_6tables9TableTypeE4fromCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
53
288
    fn from(t: TableType) -> Self {
54
288
        Self::Table(t)
55
288
    }
Unexecuted instantiation: _RNvXs_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB4_10EntityTypeINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtB6_6tables9TableTypeE4fromB8_
56
}
57
58
impl From<MemoryType> for EntityType {
59
336
    fn from(t: MemoryType) -> Self {
60
336
        Self::Memory(t)
61
336
    }
_RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB5_10EntityTypeINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtB7_8memories10MemoryTypeE4fromCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
59
336
    fn from(t: MemoryType) -> Self {
60
336
        Self::Memory(t)
61
336
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB5_10EntityTypeINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtB7_8memories10MemoryTypeE4fromB9_
62
}
63
64
impl From<GlobalType> for EntityType {
65
2.13k
    fn from(t: GlobalType) -> Self {
66
2.13k
        Self::Global(t)
67
2.13k
    }
_RNvXs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB5_10EntityTypeINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtB7_7globals10GlobalTypeE4fromCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
65
2.13k
    fn from(t: GlobalType) -> Self {
66
2.13k
        Self::Global(t)
67
2.13k
    }
Unexecuted instantiation: _RNvXs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB5_10EntityTypeINtNtCs1ujR1JRCAmI_4core7convert4FromNtNtB7_7globals10GlobalTypeE4fromB9_
68
}
69
70
impl From<TagType> for EntityType {
71
0
    fn from(t: TagType) -> Self {
72
0
        Self::Tag(t)
73
0
    }
74
}
75
76
#[cfg(feature = "wasmparser")]
77
impl TryFrom<wasmparser::TypeRef> for EntityType {
78
    type Error = ();
79
    fn try_from(type_ref: wasmparser::TypeRef) -> Result<Self, Self::Error> {
80
        Ok(match type_ref {
81
            wasmparser::TypeRef::Func(i) => EntityType::Function(i),
82
            wasmparser::TypeRef::Table(t) => EntityType::Table(t.try_into()?),
83
            wasmparser::TypeRef::Memory(m) => EntityType::Memory(m.into()),
84
            wasmparser::TypeRef::Global(g) => EntityType::Global(g.try_into()?),
85
            wasmparser::TypeRef::Tag(t) => EntityType::Tag(t.into()),
86
        })
87
    }
88
}
89
90
/// An encoder for the import section of WebAssembly modules.
91
///
92
/// # Example
93
///
94
/// ```rust
95
/// use wasm_encoder::{MemoryType, Module, ImportSection};
96
///
97
/// let mut imports = ImportSection::new();
98
/// imports.import(
99
///     "env",
100
///     "memory",
101
///     MemoryType {
102
///         minimum: 1,
103
///         maximum: None,
104
///         memory64: false,
105
///         shared: false,
106
///         page_size_log2: None,
107
///     }
108
/// );
109
///
110
/// let mut module = Module::new();
111
/// module.section(&imports);
112
///
113
/// let bytes = module.finish();
114
/// ```
115
#[derive(Clone, Debug, Default)]
116
pub struct ImportSection {
117
    bytes: Vec<u8>,
118
    num_added: u32,
119
}
120
121
impl ImportSection {
122
    /// Create a new import section encoder.
123
2.55k
    pub fn new() -> Self {
124
2.55k
        Self::default()
125
2.55k
    }
_RNvMs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB5_13ImportSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
123
2.55k
    pub fn new() -> Self {
124
2.55k
        Self::default()
125
2.55k
    }
Unexecuted instantiation: _RNvMs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB5_13ImportSection3newB9_
126
127
    /// The number of imports in the section.
128
0
    pub fn len(&self) -> u32 {
129
0
        self.num_added
130
0
    }
131
132
    /// Determines if the section is empty.
133
0
    pub fn is_empty(&self) -> bool {
134
0
        self.num_added == 0
135
0
    }
136
137
    /// Define an import in the import section.
138
4.32k
    pub fn import(&mut self, module: &str, field: &str, ty: impl Into<EntityType>) -> &mut Self {
139
4.32k
        module.encode(&mut self.bytes);
140
4.32k
        field.encode(&mut self.bytes);
141
4.32k
        ty.into().encode(&mut self.bytes);
142
4.32k
        self.num_added += 1;
143
4.32k
        self
144
4.32k
    }
_RINvMs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB6_13ImportSection6importNtB6_10EntityTypeECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
138
4.32k
    pub fn import(&mut self, module: &str, field: &str, ty: impl Into<EntityType>) -> &mut Self {
139
4.32k
        module.encode(&mut self.bytes);
140
4.32k
        field.encode(&mut self.bytes);
141
4.32k
        ty.into().encode(&mut self.bytes);
142
4.32k
        self.num_added += 1;
143
4.32k
        self
144
4.32k
    }
Unexecuted instantiation: _RINvMs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB6_13ImportSection6importpEBa_
145
}
146
147
impl Encode for ImportSection {
148
2.55k
    fn encode(&self, sink: &mut Vec<u8>) {
149
2.55k
        encode_section(sink, self.num_added, &self.bytes);
150
2.55k
    }
151
}
152
153
impl Section for ImportSection {
154
2.55k
    fn id(&self) -> u8 {
155
2.55k
        SectionId::Import.into()
156
2.55k
    }
_RNvXs5_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB5_13ImportSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
154
2.55k
    fn id(&self) -> u8 {
155
2.55k
        SectionId::Import.into()
156
2.55k
    }
Unexecuted instantiation: _RNvXs5_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core7importsNtB5_13ImportSectionNtB7_7Section2idB9_
157
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/linking.rs
Line
Count
Source (jump to first uncovered line)
1
use std::borrow::Cow;
2
3
use crate::{encode_section, CustomSection, Encode, Section, SectionId};
4
5
const VERSION: u32 = 2;
6
7
/// An encoder for the [linking custom
8
/// section](https://github.com/WebAssembly/tool-conventions/blob/master/Linking.md#linking-metadata-section).
9
///
10
/// This section is a non-standard convention that is supported by the LLVM
11
/// toolchain. It, along with associated "reloc.*" custom sections, allows you
12
/// to treat a Wasm module as a low-level object file that can be linked with
13
/// other Wasm object files to produce a final, complete Wasm module.
14
///
15
/// The linking section must come before the reloc sections.
16
///
17
/// # Example
18
///
19
/// ```
20
/// use wasm_encoder::{LinkingSection, Module, SymbolTable};
21
///
22
/// // Create a new linking section.
23
/// let mut linking = LinkingSection::new();
24
///
25
/// // Define a symbol table.
26
/// let mut sym_tab = SymbolTable::new();
27
///
28
/// // Define a function symbol in the symbol table.
29
/// let flags = SymbolTable::WASM_SYM_BINDING_LOCAL | SymbolTable::WASM_SYM_EXPORTED;
30
/// let func_index = 42;
31
/// let sym_name = "my_exported_func";
32
/// sym_tab.function(flags, func_index, Some(sym_name));
33
///
34
/// // Add the symbol table to our linking section.
35
/// linking.symbol_table(&sym_tab);
36
///
37
/// // Add the linking section to a new Wasm module and get the encoded bytes.
38
/// let mut module = Module::new();
39
/// module.section(&linking);
40
/// let wasm_bytes = module.finish();
41
/// ```
42
#[derive(Clone, Debug)]
43
pub struct LinkingSection {
44
    bytes: Vec<u8>,
45
}
46
47
impl LinkingSection {
48
    /// Construct a new encoder for the linking custom section.
49
0
    pub fn new() -> Self {
50
0
        Self::default()
51
0
    }
52
53
    // TODO: `fn segment_info` for the `WASM_SEGMENT_INFO` linking subsection.
54
55
    // TODO: `fn init_funcs` for the `WASM_INIT_FUNCS` linking subsection.
56
57
    // TODO: `fn comdat_info` for the `WASM_COMDAT_INFO` linking subsection.
58
59
    /// Add a symbol table subsection.
60
0
    pub fn symbol_table(&mut self, symbol_table: &SymbolTable) -> &mut Self {
61
0
        symbol_table.encode(&mut self.bytes);
62
0
        self
63
0
    }
64
}
65
66
impl Default for LinkingSection {
67
0
    fn default() -> Self {
68
0
        let mut bytes = Vec::new();
69
0
        VERSION.encode(&mut bytes);
70
0
        Self { bytes }
71
0
    }
72
}
73
74
impl Encode for LinkingSection {
75
0
    fn encode(&self, sink: &mut Vec<u8>) {
76
0
        CustomSection {
77
0
            name: "linking".into(),
78
0
            data: Cow::Borrowed(&self.bytes),
79
0
        }
80
0
        .encode(sink);
81
0
    }
82
}
83
84
impl Section for LinkingSection {
85
0
    fn id(&self) -> u8 {
86
0
        SectionId::Custom.into()
87
0
    }
88
}
89
90
#[allow(unused)]
91
const WASM_SEGMENT_INFO: u8 = 5;
92
#[allow(unused)]
93
const WASM_INIT_FUNCS: u8 = 6;
94
#[allow(unused)]
95
const WASM_COMDAT_INFO: u8 = 7;
96
const WASM_SYMBOL_TABLE: u8 = 8;
97
98
/// A subsection of the [linking custom section][crate::LinkingSection] that
99
/// provides extra information about the symbols present in this Wasm object
100
/// file.
101
#[derive(Clone, Debug, Default)]
102
pub struct SymbolTable {
103
    bytes: Vec<u8>,
104
    num_added: u32,
105
}
106
107
const SYMTAB_FUNCTION: u32 = 0;
108
const SYMTAB_DATA: u32 = 1;
109
const SYMTAB_GLOBAL: u32 = 2;
110
#[allow(unused)]
111
const SYMTAB_SECTION: u32 = 3;
112
#[allow(unused)]
113
const SYMTAB_TAG: u32 = 4;
114
const SYMTAB_TABLE: u32 = 5;
115
116
impl SymbolTable {
117
    /// Construct a new symbol table subsection encoder.
118
0
    pub fn new() -> Self {
119
0
        SymbolTable {
120
0
            bytes: vec![],
121
0
            num_added: 0,
122
0
        }
123
0
    }
124
125
    /// Define a function symbol in this symbol table.
126
    ///
127
    /// The `name` must be omitted if `index` references an imported table and
128
    /// the `WASM_SYM_EXPLICIT_NAME` flag is not set.
129
0
    pub fn function(&mut self, flags: u32, index: u32, name: Option<&str>) -> &mut Self {
130
0
        SYMTAB_FUNCTION.encode(&mut self.bytes);
131
0
        flags.encode(&mut self.bytes);
132
0
        index.encode(&mut self.bytes);
133
0
        if let Some(name) = name {
134
0
            name.encode(&mut self.bytes);
135
0
        }
136
0
        self.num_added += 1;
137
0
        self
138
0
    }
139
140
    /// Define a global symbol in this symbol table.
141
    ///
142
    /// The `name` must be omitted if `index` references an imported table and
143
    /// the `WASM_SYM_EXPLICIT_NAME` flag is not set.
144
0
    pub fn global(&mut self, flags: u32, index: u32, name: Option<&str>) -> &mut Self {
145
0
        SYMTAB_GLOBAL.encode(&mut self.bytes);
146
0
        flags.encode(&mut self.bytes);
147
0
        index.encode(&mut self.bytes);
148
0
        if let Some(name) = name {
149
0
            name.encode(&mut self.bytes);
150
0
        }
151
0
        self.num_added += 1;
152
0
        self
153
0
    }
154
155
    // TODO: tags
156
157
    /// Define a table symbol in this symbol table.
158
    ///
159
    /// The `name` must be omitted if `index` references an imported table and
160
    /// the `WASM_SYM_EXPLICIT_NAME` flag is not set.
161
0
    pub fn table(&mut self, flags: u32, index: u32, name: Option<&str>) -> &mut Self {
162
0
        SYMTAB_TABLE.encode(&mut self.bytes);
163
0
        flags.encode(&mut self.bytes);
164
0
        index.encode(&mut self.bytes);
165
0
        if let Some(name) = name {
166
0
            name.encode(&mut self.bytes);
167
0
        }
168
0
        self.num_added += 1;
169
0
        self
170
0
    }
171
172
    /// Add a data symbol to this symbol table.
173
0
    pub fn data(
174
0
        &mut self,
175
0
        flags: u32,
176
0
        name: &str,
177
0
        definition: Option<DataSymbolDefinition>,
178
0
    ) -> &mut Self {
179
0
        SYMTAB_DATA.encode(&mut self.bytes);
180
0
        flags.encode(&mut self.bytes);
181
0
        name.encode(&mut self.bytes);
182
0
        if let Some(def) = definition {
183
0
            def.index.encode(&mut self.bytes);
184
0
            def.offset.encode(&mut self.bytes);
185
0
            def.size.encode(&mut self.bytes);
186
0
        }
187
0
        self.num_added += 1;
188
0
        self
189
0
    }
190
191
    // TODO: sections
192
193
    /// This is a weak symbol.
194
    ///
195
    /// This flag is mutually exclusive with `WASM_SYM_BINDING_LOCAL`.
196
    ///
197
    /// When linking multiple modules defining the same symbol, all weak
198
    /// definitions are discarded if any strong definitions exist; then if
199
    /// multiple weak definitions exist all but one (unspecified) are discarded;
200
    /// and finally it is an error if more than one definition remains.
201
    pub const WASM_SYM_BINDING_WEAK: u32 = 0x1;
202
203
    /// This is a local symbol.
204
    ///
205
    /// This flag is mutually exclusive with `WASM_SYM_BINDING_WEAK`.
206
    ///
207
    /// Local symbols are not to be exported, or linked to other
208
    /// modules/sections. The names of all non-local symbols must be unique, but
209
    /// the names of local symbols are not considered for uniqueness. A local
210
    /// function or global symbol cannot reference an import.
211
    pub const WASM_SYM_BINDING_LOCAL: u32 = 0x02;
212
213
    /// This is a hidden symbol.
214
    ///
215
    /// Hidden symbols are not to be exported when performing the final link,
216
    /// but may be linked to other modules.
217
    pub const WASM_SYM_VISIBILITY_HIDDEN: u32 = 0x04;
218
219
    /// This symbol is not defined.
220
    ///
221
    /// For non-data symbols, this must match whether the symbol is an import or
222
    /// is defined; for data symbols, determines whether a segment is specified.
223
    pub const WASM_SYM_UNDEFINED: u32 = 0x10;
224
225
    /// This symbol is intended to be exported from the wasm module to the host
226
    /// environment.
227
    ///
228
    /// This differs from the visibility flags in that it effects the static
229
    /// linker.
230
    pub const WASM_SYM_EXPORTED: u32 = 0x20;
231
232
    /// This symbol uses an explicit symbol name, rather than reusing the name
233
    /// from a wasm import.
234
    ///
235
    /// This allows it to remap imports from foreign WebAssembly modules into
236
    /// local symbols with different names.
237
    pub const WASM_SYM_EXPLICIT_NAME: u32 = 0x40;
238
239
    /// This symbol is intended to be included in the linker output, regardless
240
    /// of whether it is used by the program.
241
    pub const WASM_SYM_NO_STRIP: u32 = 0x80;
242
}
243
244
impl Encode for SymbolTable {
245
0
    fn encode(&self, sink: &mut Vec<u8>) {
246
0
        sink.push(WASM_SYMBOL_TABLE);
247
0
        encode_section(sink, self.num_added, &self.bytes);
248
0
    }
249
}
250
251
/// The definition of a data symbol within a symbol table.
252
#[derive(Clone, Debug)]
253
pub struct DataSymbolDefinition {
254
    /// The index of the data segment that this symbol is in.
255
    pub index: u32,
256
    /// The offset of this symbol within its segment.
257
    pub offset: u32,
258
    /// The byte size (which can be zero) of this data symbol.
259
    ///
260
    /// Note that `offset + size` must be less than or equal to the segment's
261
    /// size.
262
    pub size: u32,
263
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/memories.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, Encode, Section, SectionId};
2
3
/// An encoder for the memory section.
4
///
5
/// Memory sections are only supported for modules.
6
///
7
/// # Example
8
///
9
/// ```
10
/// use wasm_encoder::{Module, MemorySection, MemoryType};
11
///
12
/// let mut memories = MemorySection::new();
13
/// memories.memory(MemoryType {
14
///     minimum: 1,
15
///     maximum: None,
16
///     memory64: false,
17
///     shared: false,
18
///     page_size_log2: None,
19
/// });
20
///
21
/// let mut module = Module::new();
22
/// module.section(&memories);
23
///
24
/// let wasm_bytes = module.finish();
25
/// ```
26
#[derive(Clone, Default, Debug)]
27
pub struct MemorySection {
28
    bytes: Vec<u8>,
29
    num_added: u32,
30
}
31
32
impl MemorySection {
33
    /// Create a new memory section encoder.
34
1.41k
    pub fn new() -> Self {
35
1.41k
        Self::default()
36
1.41k
    }
_RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core8memoriesNtB2_13MemorySection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
34
1.41k
    pub fn new() -> Self {
35
1.41k
        Self::default()
36
1.41k
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core8memoriesNtB2_13MemorySection3newB6_
37
38
    /// The number of memories in the section.
39
0
    pub fn len(&self) -> u32 {
40
0
        self.num_added
41
0
    }
42
43
    /// Determines if the section is empty.
44
0
    pub fn is_empty(&self) -> bool {
45
0
        self.num_added == 0
46
0
    }
47
48
    /// Define a memory.
49
1.41k
    pub fn memory(&mut self, memory_type: MemoryType) -> &mut Self {
50
1.41k
        memory_type.encode(&mut self.bytes);
51
1.41k
        self.num_added += 1;
52
1.41k
        self
53
1.41k
    }
54
}
55
56
impl Encode for MemorySection {
57
1.41k
    fn encode(&self, sink: &mut Vec<u8>) {
58
1.41k
        encode_section(sink, self.num_added, &self.bytes);
59
1.41k
    }
60
}
61
62
impl Section for MemorySection {
63
1.41k
    fn id(&self) -> u8 {
64
1.41k
        SectionId::Memory.into()
65
1.41k
    }
_RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core8memoriesNtB5_13MemorySectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
63
1.41k
    fn id(&self) -> u8 {
64
1.41k
        SectionId::Memory.into()
65
1.41k
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core8memoriesNtB5_13MemorySectionNtB7_7Section2idB9_
66
}
67
68
/// A memory's type.
69
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
70
pub struct MemoryType {
71
    /// Minimum size, in pages, of this memory
72
    pub minimum: u64,
73
    /// Maximum size, in pages, of this memory
74
    pub maximum: Option<u64>,
75
    /// Whether or not this is a 64-bit memory.
76
    pub memory64: bool,
77
    /// Whether or not this memory is shared.
78
    pub shared: bool,
79
    /// The log base 2 of a custom page size for this memory.
80
    ///
81
    /// The default page size for Wasm memories is 64KiB, i.e. 2<sup>16</sup> or
82
    /// `65536`.
83
    ///
84
    /// After the introduction of [the custom-page-sizes
85
    /// proposal](https://github.com/WebAssembly/custom-page-sizes), Wasm can
86
    /// customize the page size. It must be a power of two that is less than or
87
    /// equal to 64KiB. Attempting to encode an invalid page size may panic.
88
    pub page_size_log2: Option<u32>,
89
}
90
91
impl Encode for MemoryType {
92
1.74k
    fn encode(&self, sink: &mut Vec<u8>) {
93
1.74k
        let mut flags = 0;
94
1.74k
        if self.maximum.is_some() {
95
774
            flags |= 0b0001;
96
974
        }
97
1.74k
        if self.shared {
98
0
            flags |= 0b0010;
99
1.74k
        }
100
1.74k
        if self.memory64 {
101
0
            flags |= 0b0100;
102
1.74k
        }
103
1.74k
        if self.page_size_log2.is_some() {
104
0
            flags |= 0b1000;
105
1.74k
        }
106
1.74k
        sink.push(flags);
107
1.74k
        self.minimum.encode(sink);
108
1.74k
        if let Some(max) = self.maximum {
109
774
            max.encode(sink);
110
974
        }
111
1.74k
        if let Some(p) = self.page_size_log2 {
112
0
            p.encode(sink);
113
1.74k
        }
114
1.74k
    }
115
}
116
117
#[cfg(feature = "wasmparser")]
118
impl From<wasmparser::MemoryType> for MemoryType {
119
    fn from(memory_ty: wasmparser::MemoryType) -> Self {
120
        MemoryType {
121
            minimum: memory_ty.initial,
122
            maximum: memory_ty.maximum,
123
            memory64: memory_ty.memory64,
124
            shared: memory_ty.shared,
125
            page_size_log2: memory_ty.page_size_log2,
126
        }
127
    }
128
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/names.rs
Line
Count
Source (jump to first uncovered line)
1
use std::borrow::Cow;
2
3
use crate::{encoding_size, CustomSection, Encode, Section, SectionId};
4
5
/// An encoder for the custom `name` section.
6
///
7
/// # Example
8
///
9
/// ```
10
/// use wasm_encoder::{Module, NameSection, NameMap};
11
///
12
/// let mut names = NameSection::new();
13
/// names.module("the module name");
14
///
15
/// let mut function_names = NameMap::new();
16
/// function_names.append(0, "name of function 0");
17
/// function_names.append(1, "a better function");
18
/// function_names.append(3, "the best function");
19
/// names.functions(&function_names);
20
///
21
/// let mut module = Module::new();
22
/// module.section(&names);
23
///
24
/// let wasm_bytes = module.finish();
25
/// ```
26
#[derive(Clone, Debug, Default)]
27
pub struct NameSection {
28
    bytes: Vec<u8>,
29
}
30
31
enum Subsection {
32
    // Currently specified in the wasm spec's appendix
33
    Module = 0,
34
    Function = 1,
35
    Local = 2,
36
37
    // specified as part of the extended name section proposal
38
    //
39
    // https://github.com/WebAssembly/extended-name-section/blob/main/proposals/extended-name-section/Overview.md
40
    Label = 3,
41
    Type = 4,
42
    Table = 5,
43
    Memory = 6,
44
    Global = 7,
45
    Element = 8,
46
    Data = 9,
47
48
    // https://github.com/WebAssembly/gc/issues/193
49
    Field = 10,
50
51
    // https://github.com/WebAssembly/exception-handling/pull/213
52
    Tag = 11,
53
}
54
55
impl NameSection {
56
    /// Creates a new blank `name` custom section.
57
0
    pub fn new() -> Self {
58
0
        Self::default()
59
0
    }
60
61
    /// Appends a module name subsection to this section.
62
    ///
63
    /// This will indicate that the name of the entire module should be the
64
    /// `name` specified. Note that this should be encoded first before other
65
    /// subsections.
66
0
    pub fn module(&mut self, name: &str) {
67
0
        let len = encoding_size(u32::try_from(name.len()).unwrap());
68
0
        self.subsection_header(Subsection::Module, len + name.len());
69
0
        name.encode(&mut self.bytes);
70
0
    }
71
72
    /// Appends a subsection for the names of all functions in this wasm module.
73
    ///
74
    /// Function names are declared in the `names` map provided where the index
75
    /// in the map corresponds to the wasm index of the function. This section
76
    /// should come after the module name subsection (if present) and before the
77
    /// locals subsection (if present).
78
0
    pub fn functions(&mut self, names: &NameMap) {
79
0
        self.subsection_header(Subsection::Function, names.size());
80
0
        names.encode(&mut self.bytes);
81
0
    }
82
83
    /// Appends a subsection for the names of locals within functions in this
84
    /// wasm module.
85
    ///
86
    /// This section should come after the function name subsection (if present)
87
    /// and before the labels subsection (if present).
88
0
    pub fn locals(&mut self, names: &IndirectNameMap) {
89
0
        self.subsection_header(Subsection::Local, names.size());
90
0
        names.encode(&mut self.bytes);
91
0
    }
92
93
    /// Appends a subsection for the names of labels within functions in this
94
    /// wasm module.
95
    ///
96
    /// This section should come after the local name subsection (if present)
97
    /// and before the type subsection (if present).
98
0
    pub fn labels(&mut self, names: &IndirectNameMap) {
99
0
        self.subsection_header(Subsection::Label, names.size());
100
0
        names.encode(&mut self.bytes);
101
0
    }
102
103
    /// Appends a subsection for the names of all types in this wasm module.
104
    ///
105
    /// This section should come after the label name subsection (if present)
106
    /// and before the table subsection (if present).
107
0
    pub fn types(&mut self, names: &NameMap) {
108
0
        self.subsection_header(Subsection::Type, names.size());
109
0
        names.encode(&mut self.bytes);
110
0
    }
111
112
    /// Appends a subsection for the names of all tables in this wasm module.
113
    ///
114
    /// This section should come after the type name subsection (if present)
115
    /// and before the memory subsection (if present).
116
0
    pub fn tables(&mut self, names: &NameMap) {
117
0
        self.subsection_header(Subsection::Table, names.size());
118
0
        names.encode(&mut self.bytes);
119
0
    }
120
121
    /// Appends a subsection for the names of all memories in this wasm module.
122
    ///
123
    /// This section should come after the table name subsection (if present)
124
    /// and before the global subsection (if present).
125
0
    pub fn memories(&mut self, names: &NameMap) {
126
0
        self.subsection_header(Subsection::Memory, names.size());
127
0
        names.encode(&mut self.bytes);
128
0
    }
129
130
    /// Appends a subsection for the names of all globals in this wasm module.
131
    ///
132
    /// This section should come after the memory name subsection (if present)
133
    /// and before the element subsection (if present).
134
0
    pub fn globals(&mut self, names: &NameMap) {
135
0
        self.subsection_header(Subsection::Global, names.size());
136
0
        names.encode(&mut self.bytes);
137
0
    }
138
139
    /// Appends a subsection for the names of all elements in this wasm module.
140
    ///
141
    /// This section should come after the global name subsection (if present)
142
    /// and before the data subsection (if present).
143
0
    pub fn elements(&mut self, names: &NameMap) {
144
0
        self.subsection_header(Subsection::Element, names.size());
145
0
        names.encode(&mut self.bytes);
146
0
    }
147
148
    /// Appends a subsection for the names of all data in this wasm module.
149
    ///
150
    /// This section should come after the element name subsection (if present)
151
    /// and before the field subsection (if present).
152
0
    pub fn data(&mut self, names: &NameMap) {
153
0
        self.subsection_header(Subsection::Data, names.size());
154
0
        names.encode(&mut self.bytes);
155
0
    }
156
157
    /// Appends a subsection for the names of all tags in this wasm module.
158
    ///
159
    /// This section should come after the data name subsection (if present).
160
0
    pub fn tag(&mut self, names: &NameMap) {
161
0
        self.subsection_header(Subsection::Tag, names.size());
162
0
        names.encode(&mut self.bytes);
163
0
    }
164
165
    /// Appends a subsection for the names of fields within types in this
166
    /// wasm module.
167
    ///
168
    /// This section should come after the data name subsection (if present)
169
    /// and before the tag subsection (if present).
170
0
    pub fn fields(&mut self, names: &IndirectNameMap) {
171
0
        self.subsection_header(Subsection::Field, names.size());
172
0
        names.encode(&mut self.bytes);
173
0
    }
174
175
    /// Appends a subsection for the names of all tags in this wasm module.
176
    ///
177
    /// This section should come after the field name subsection (if present).
178
0
    pub fn tags(&mut self, names: &NameMap) {
179
0
        self.subsection_header(Subsection::Tag, names.size());
180
0
        names.encode(&mut self.bytes);
181
0
    }
182
183
0
    fn subsection_header(&mut self, id: Subsection, len: usize) {
184
0
        self.bytes.push(id as u8);
185
0
        len.encode(&mut self.bytes);
186
0
    }
187
188
    /// View the encoded section as a CustomSection.
189
0
    pub fn as_custom<'a>(&'a self) -> CustomSection<'a> {
190
0
        CustomSection {
191
0
            name: "name".into(),
192
0
            data: Cow::Borrowed(&self.bytes),
193
0
        }
194
0
    }
195
}
196
197
impl Encode for NameSection {
198
0
    fn encode(&self, sink: &mut Vec<u8>) {
199
0
        self.as_custom().encode(sink);
200
0
    }
201
}
202
203
impl Section for NameSection {
204
0
    fn id(&self) -> u8 {
205
0
        SectionId::Custom.into()
206
0
    }
207
}
208
209
/// A map used to name items in a wasm module, organized by naming each
210
/// individual index.
211
///
212
/// This is used in conjunction with [`NameSection::functions`] and simlar
213
/// methods.
214
#[derive(Clone, Debug, Default)]
215
pub struct NameMap {
216
    bytes: Vec<u8>,
217
    count: u32,
218
}
219
220
impl NameMap {
221
    /// Creates a new empty `NameMap`.
222
0
    pub fn new() -> NameMap {
223
0
        NameMap {
224
0
            bytes: vec![],
225
0
            count: 0,
226
0
        }
227
0
    }
228
229
    /// Adds a an entry where the item at `idx` has the `name` specified.
230
    ///
231
    /// Note that indices should be appended in ascending order of the index
232
    /// value. Each index may only be named once, but not all indices must be
233
    /// named (e.g. `0 foo; 1 bar; 7 qux` is valid but `0 foo; 0 bar` is not).
234
    /// Names do not have to be unique (e.g. `0 foo; 1 foo; 2 foo` is valid).
235
0
    pub fn append(&mut self, idx: u32, name: &str) {
236
0
        idx.encode(&mut self.bytes);
237
0
        name.encode(&mut self.bytes);
238
0
        self.count += 1;
239
0
    }
240
241
0
    pub(crate) fn size(&self) -> usize {
242
0
        encoding_size(self.count) + self.bytes.len()
243
0
    }
244
245
    /// Returns whether no names have been added to this map.
246
0
    pub fn is_empty(&self) -> bool {
247
0
        self.count == 0
248
0
    }
249
}
250
251
impl Encode for NameMap {
252
0
    fn encode(&self, sink: &mut Vec<u8>) {
253
0
        self.count.encode(sink);
254
0
        sink.extend(&self.bytes);
255
0
    }
256
}
257
258
/// A map used to describe names with two levels of indirection, as opposed to a
259
/// [`NameMap`] which has one level of indirection.
260
///
261
/// This naming map is used with [`NameSection::locals`], for example.
262
#[derive(Clone, Debug, Default)]
263
pub struct IndirectNameMap {
264
    bytes: Vec<u8>,
265
    count: u32,
266
}
267
268
impl IndirectNameMap {
269
    /// Creates a new empty name map.
270
0
    pub fn new() -> IndirectNameMap {
271
0
        IndirectNameMap {
272
0
            bytes: vec![],
273
0
            count: 0,
274
0
        }
275
0
    }
276
277
    /// Adds a new entry where the item at `idx` has sub-items named within
278
    /// `names` as specified.
279
    ///
280
    /// For example if this is describing local names then `idx` is a function
281
    /// index where the indexes within `names` are local indices.
282
0
    pub fn append(&mut self, idx: u32, names: &NameMap) {
283
0
        idx.encode(&mut self.bytes);
284
0
        names.encode(&mut self.bytes);
285
0
        self.count += 1;
286
0
    }
287
288
0
    fn size(&self) -> usize {
289
0
        encoding_size(self.count) + self.bytes.len()
290
0
    }
291
}
292
293
impl Encode for IndirectNameMap {
294
0
    fn encode(&self, sink: &mut Vec<u8>) {
295
0
        self.count.encode(sink);
296
0
        sink.extend(&self.bytes);
297
0
    }
298
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/producers.rs
Line
Count
Source (jump to first uncovered line)
1
use std::borrow::Cow;
2
3
use crate::{CustomSection, Encode, Section, SectionId};
4
5
/// An encoder for the [producers custom
6
/// section](https://github.com/WebAssembly/tool-conventions/blob/main/ProducersSection.md).
7
///
8
/// This section is a non-standard convention that is supported by many toolchains.
9
///
10
/// # Example
11
///
12
/// ```
13
/// use wasm_encoder::{ProducersSection, ProducersField, Module};
14
///
15
/// // Create a new producers section.
16
/// let mut field = ProducersField::new();
17
/// field.value("clang", "14.0.4");
18
/// field.value("rustc", "1.66.1 (90743e729 2023-01-10)");
19
/// let mut producers = ProducersSection::new();
20
/// producers.field("processed-by", &field);
21
///
22
/// // Add the producers section to a new Wasm module and get the encoded bytes.
23
/// let mut module = Module::new();
24
/// module.section(&producers);
25
/// let wasm_bytes = module.finish();
26
/// ```
27
#[derive(Clone, Debug)]
28
pub struct ProducersSection {
29
    bytes: Vec<u8>,
30
    num_fields: u32,
31
}
32
33
impl ProducersSection {
34
    /// Construct an empty encoder for the producers custom section.
35
0
    pub fn new() -> Self {
36
0
        Self::default()
37
0
    }
38
39
    /// Add a field to the section. The spec recommends names for this section
40
    /// are "language", "processed-by", and "sdk".  Each field in section must
41
    /// have a unique name.
42
0
    pub fn field(&mut self, name: &str, values: &ProducersField) -> &mut Self {
43
0
        name.encode(&mut self.bytes);
44
0
        values.encode(&mut self.bytes);
45
0
        self.num_fields += 1;
46
0
        self
47
0
    }
48
}
49
50
impl Default for ProducersSection {
51
0
    fn default() -> Self {
52
0
        Self {
53
0
            bytes: Vec::new(),
54
0
            num_fields: 0,
55
0
        }
56
0
    }
57
}
58
59
impl Encode for ProducersSection {
60
0
    fn encode(&self, sink: &mut Vec<u8>) {
61
0
        let mut data = Vec::new();
62
0
        self.num_fields.encode(&mut data);
63
0
        data.extend(&self.bytes);
64
0
65
0
        CustomSection {
66
0
            name: "producers".into(),
67
0
            data: Cow::Borrowed(&data),
68
0
        }
69
0
        .encode(sink);
70
0
    }
71
}
72
73
impl Section for ProducersSection {
74
0
    fn id(&self) -> u8 {
75
0
        SectionId::Custom.into()
76
0
    }
77
}
78
79
/// The value of a field in the producers custom section
80
#[derive(Clone, Debug)]
81
pub struct ProducersField {
82
    bytes: Vec<u8>,
83
    num_values: u32,
84
}
85
86
impl ProducersField {
87
    /// Construct an empty encoder for a producers field value
88
0
    pub fn new() -> Self {
89
0
        ProducersField::default()
90
0
    }
91
92
    /// Add a value to the field encoder. Each value in a field must have a
93
    /// unique name. If there is no sensible value for `version`, use the
94
    /// empty string.
95
0
    pub fn value(&mut self, name: &str, version: &str) -> &mut Self {
96
0
        name.encode(&mut self.bytes);
97
0
        version.encode(&mut self.bytes);
98
0
        self.num_values += 1;
99
0
        self
100
0
    }
101
}
102
103
impl Default for ProducersField {
104
0
    fn default() -> Self {
105
0
        Self {
106
0
            bytes: Vec::new(),
107
0
            num_values: 0,
108
0
        }
109
0
    }
110
}
111
112
impl Encode for ProducersField {
113
0
    fn encode(&self, sink: &mut Vec<u8>) {
114
0
        self.num_values.encode(sink);
115
0
        sink.extend(&self.bytes);
116
0
    }
117
}
118
119
#[cfg(test)]
120
mod test {
121
    #[test]
122
    fn roundtrip_example() {
123
        use crate::{Module, ProducersField, ProducersSection};
124
        use wasmparser::{KnownCustom, Parser, Payload};
125
126
        // Create a new producers section.
127
        let mut field = ProducersField::new();
128
        field.value("clang", "14.0.4");
129
        field.value("rustc", "1.66.1");
130
        let mut producers = ProducersSection::new();
131
        producers.field("processed-by", &field);
132
133
        // Add the producers section to a new Wasm module and get the encoded bytes.
134
        let mut module = Module::new();
135
        module.section(&producers);
136
        let wasm_bytes = module.finish();
137
138
        let mut parser = Parser::new(0).parse_all(&wasm_bytes);
139
        let payload = parser
140
            .next()
141
            .expect("parser is not empty")
142
            .expect("element is a payload");
143
        match payload {
144
            Payload::Version { .. } => {}
145
            _ => panic!(""),
146
        }
147
        let payload = parser
148
            .next()
149
            .expect("parser is not empty")
150
            .expect("element is a payload");
151
        match payload {
152
            Payload::CustomSection(c) => {
153
                assert_eq!(c.name(), "producers");
154
                let mut section = match c.as_known() {
155
                    KnownCustom::Producers(s) => s.into_iter(),
156
                    _ => panic!("unknown custom section"),
157
                };
158
                let field = section
159
                    .next()
160
                    .expect("section has an element")
161
                    .expect("element is a producers field");
162
                assert_eq!(field.name, "processed-by");
163
                let mut values = field.values.into_iter();
164
                let value = values
165
                    .next()
166
                    .expect("values has an element")
167
                    .expect("element is a producers field value");
168
                assert_eq!(value.name, "clang");
169
                assert_eq!(value.version, "14.0.4");
170
171
                let value = values
172
                    .next()
173
                    .expect("values has another element")
174
                    .expect("element is a producers field value");
175
                assert_eq!(value.name, "rustc");
176
                assert_eq!(value.version, "1.66.1");
177
            }
178
            _ => panic!("unexpected payload"),
179
        }
180
    }
181
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/start.rs
Line
Count
Source
1
use crate::{encoding_size, Encode, Section, SectionId};
2
3
/// An encoder for the start section of WebAssembly modules.
4
///
5
/// # Example
6
///
7
/// Note: this doesn't actually define the function at index 0, its type, or its
8
/// code body, so the resulting Wasm module will be invalid. See `TypeSection`,
9
/// `FunctionSection`, and `CodeSection` for details on how to generate those
10
/// things.
11
///
12
/// ```
13
/// use wasm_encoder::{Module, StartSection};
14
///
15
/// let start = StartSection { function_index: 0 };
16
///
17
/// let mut module = Module::new();
18
/// module.section(&start);
19
///
20
/// let wasm_bytes = module.finish();
21
/// ```
22
#[derive(Clone, Copy, Debug)]
23
pub struct StartSection {
24
    /// The index of the start function.
25
    pub function_index: u32,
26
}
27
28
impl Encode for StartSection {
29
582
    fn encode(&self, sink: &mut Vec<u8>) {
30
582
        encoding_size(self.function_index).encode(sink);
31
582
        self.function_index.encode(sink);
32
582
    }
33
}
34
35
impl Section for StartSection {
36
582
    fn id(&self) -> u8 {
37
582
        SectionId::Start.into()
38
582
    }
_RNvXs_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5startNtB4_12StartSectionNtB6_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
36
582
    fn id(&self) -> u8 {
37
582
        SectionId::Start.into()
38
582
    }
Unexecuted instantiation: _RNvXs_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5startNtB4_12StartSectionNtB6_7Section2idB8_
39
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/tables.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, ConstExpr, Encode, RefType, Section, SectionId, ValType};
2
3
/// An encoder for the table section.
4
///
5
/// Table sections are only supported for modules.
6
///
7
/// # Example
8
///
9
/// ```
10
/// use wasm_encoder::{Module, TableSection, TableType, RefType};
11
///
12
/// let mut tables = TableSection::new();
13
/// tables.table(TableType {
14
///     element_type: RefType::FUNCREF,
15
///     minimum: 128,
16
///     maximum: None,
17
///     table64: false,
18
/// });
19
///
20
/// let mut module = Module::new();
21
/// module.section(&tables);
22
///
23
/// let wasm_bytes = module.finish();
24
/// ```
25
#[derive(Clone, Default, Debug)]
26
pub struct TableSection {
27
    bytes: Vec<u8>,
28
    num_added: u32,
29
}
30
31
impl TableSection {
32
    /// Construct a new table section encoder.
33
1.03k
    pub fn new() -> Self {
34
1.03k
        Self::default()
35
1.03k
    }
_RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core6tablesNtB2_12TableSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
33
1.03k
    pub fn new() -> Self {
34
1.03k
        Self::default()
35
1.03k
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core6tablesNtB2_12TableSection3newB6_
36
37
    /// The number of tables in the section.
38
0
    pub fn len(&self) -> u32 {
39
0
        self.num_added
40
0
    }
41
42
    /// Determines if the section is empty.
43
0
    pub fn is_empty(&self) -> bool {
44
0
        self.num_added == 0
45
0
    }
46
47
    /// Define a table.
48
1.03k
    pub fn table(&mut self, table_type: TableType) -> &mut Self {
49
1.03k
        table_type.encode(&mut self.bytes);
50
1.03k
        self.num_added += 1;
51
1.03k
        self
52
1.03k
    }
53
54
    /// Define a table with an explicit initialization expression.
55
    ///
56
    /// Note that this is part of the function-references proposal.
57
0
    pub fn table_with_init(&mut self, table_type: TableType, init: &ConstExpr) -> &mut Self {
58
0
        self.bytes.push(0x40);
59
0
        self.bytes.push(0x00);
60
0
        table_type.encode(&mut self.bytes);
61
0
        init.encode(&mut self.bytes);
62
0
        self.num_added += 1;
63
0
        self
64
0
    }
65
}
66
67
impl Encode for TableSection {
68
1.03k
    fn encode(&self, sink: &mut Vec<u8>) {
69
1.03k
        encode_section(sink, self.num_added, &self.bytes);
70
1.03k
    }
71
}
72
73
impl Section for TableSection {
74
1.03k
    fn id(&self) -> u8 {
75
1.03k
        SectionId::Table.into()
76
1.03k
    }
_RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core6tablesNtB5_12TableSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
74
1.03k
    fn id(&self) -> u8 {
75
1.03k
        SectionId::Table.into()
76
1.03k
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core6tablesNtB5_12TableSectionNtB7_7Section2idB9_
77
}
78
79
/// A table's type.
80
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
81
pub struct TableType {
82
    /// The table's element type.
83
    pub element_type: RefType,
84
    /// Whether or not this is a 64-bit table.
85
    pub table64: bool,
86
    /// Minimum size, in elements, of this table
87
    pub minimum: u64,
88
    /// Maximum size, in elements, of this table
89
    pub maximum: Option<u64>,
90
}
91
92
impl TableType {
93
    /// Returns the type used to index this table.
94
0
    pub fn index_type(&self) -> ValType {
95
0
        if self.table64 {
96
0
            ValType::I64
97
        } else {
98
0
            ValType::I32
99
        }
100
0
    }
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core6tablesNtB5_9TableType10index_typeCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core6tablesNtB5_9TableType10index_typeB9_
101
}
102
103
impl Encode for TableType {
104
1.32k
    fn encode(&self, sink: &mut Vec<u8>) {
105
1.32k
        let mut flags = 0;
106
1.32k
        if self.maximum.is_some() {
107
561
            flags |= 0b001;
108
766
        }
109
1.32k
        if self.table64 {
110
0
            flags |= 0b100;
111
1.32k
        }
112
113
1.32k
        self.element_type.encode(sink);
114
1.32k
        sink.push(flags);
115
1.32k
        self.minimum.encode(sink);
116
117
1.32k
        if let Some(max) = self.maximum {
118
561
            max.encode(sink);
119
766
        }
120
1.32k
    }
121
}
122
123
#[cfg(feature = "wasmparser")]
124
impl TryFrom<wasmparser::TableType> for TableType {
125
    type Error = ();
126
    fn try_from(table_ty: wasmparser::TableType) -> Result<Self, Self::Error> {
127
        Ok(TableType {
128
            element_type: table_ty.element_type.try_into()?,
129
            minimum: table_ty.initial,
130
            maximum: table_ty.maximum,
131
            table64: table_ty.table64,
132
        })
133
    }
134
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/tags.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, Encode, Section, SectionId};
2
3
/// An encoder for the tag section.
4
///
5
/// # Example
6
///
7
/// ```
8
/// use wasm_encoder::{Module, TagSection, TagType, TagKind};
9
///
10
/// let mut tags = TagSection::new();
11
/// tags.tag(TagType {
12
///     kind: TagKind::Exception,
13
///     func_type_idx: 0,
14
/// });
15
///
16
/// let mut module = Module::new();
17
/// module.section(&tags);
18
///
19
/// let wasm_bytes = module.finish();
20
/// ```
21
#[derive(Clone, Default, Debug)]
22
pub struct TagSection {
23
    bytes: Vec<u8>,
24
    num_added: u32,
25
}
26
27
impl TagSection {
28
    /// Create a new tag section encoder.
29
0
    pub fn new() -> Self {
30
0
        Self::default()
31
0
    }
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4tagsNtB2_10TagSection3newCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMNtNtCs5Pk8z11FdwQ_12wasm_encoder4core4tagsNtB2_10TagSection3newB6_
32
33
    /// The number of tags in the section.
34
0
    pub fn len(&self) -> u32 {
35
0
        self.num_added
36
0
    }
37
38
    /// Determines if the section is empty.
39
0
    pub fn is_empty(&self) -> bool {
40
0
        self.num_added == 0
41
0
    }
42
43
    /// Define a tag.
44
0
    pub fn tag(&mut self, tag_type: TagType) -> &mut Self {
45
0
        tag_type.encode(&mut self.bytes);
46
0
        self.num_added += 1;
47
0
        self
48
0
    }
49
}
50
51
impl Encode for TagSection {
52
0
    fn encode(&self, sink: &mut Vec<u8>) {
53
0
        encode_section(sink, self.num_added, &self.bytes);
54
0
    }
55
}
56
57
impl Section for TagSection {
58
0
    fn id(&self) -> u8 {
59
0
        SectionId::Tag.into()
60
0
    }
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4tagsNtB5_10TagSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core4tagsNtB5_10TagSectionNtB7_7Section2idB9_
61
}
62
63
/// Represents a tag kind.
64
#[repr(u8)]
65
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
66
pub enum TagKind {
67
    /// The tag is an exception type.
68
    Exception = 0x0,
69
}
70
71
#[cfg(feature = "wasmparser")]
72
impl From<wasmparser::TagKind> for TagKind {
73
    fn from(kind: wasmparser::TagKind) -> Self {
74
        match kind {
75
            wasmparser::TagKind::Exception => TagKind::Exception,
76
        }
77
    }
78
}
79
80
/// A tag's type.
81
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
82
pub struct TagType {
83
    /// The kind of tag
84
    pub kind: TagKind,
85
    /// The function type this tag uses
86
    pub func_type_idx: u32,
87
}
88
89
impl Encode for TagType {
90
0
    fn encode(&self, sink: &mut Vec<u8>) {
91
0
        sink.push(self.kind as u8);
92
0
        self.func_type_idx.encode(sink);
93
0
    }
94
}
95
96
#[cfg(feature = "wasmparser")]
97
impl From<wasmparser::TagType> for TagType {
98
    fn from(tag_ty: wasmparser::TagType) -> Self {
99
        TagType {
100
            kind: tag_ty.kind.into(),
101
            func_type_idx: tag_ty.func_type_idx,
102
        }
103
    }
104
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/core/types.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{encode_section, Encode, Section, SectionId};
2
3
/// Represents a subtype of possible other types in a WebAssembly module.
4
#[derive(Debug, Clone)]
5
pub struct SubType {
6
    /// Is the subtype final.
7
    pub is_final: bool,
8
    /// The list of supertype indexes. As of GC MVP, there can be at most one supertype.
9
    pub supertype_idx: Option<u32>,
10
    /// The composite type of the subtype.
11
    pub composite_type: CompositeType,
12
}
13
14
impl Encode for SubType {
15
5.68k
    fn encode(&self, sink: &mut Vec<u8>) {
16
5.68k
        // We only need to emit a prefix byte before the actual composite type
17
5.68k
        // when either the type is not final or it has a declared super type.
18
5.68k
        if self.supertype_idx.is_some() || !self.is_final {
19
0
            sink.push(if self.is_final { 0x4f } else { 0x50 });
20
0
            self.supertype_idx.encode(sink);
21
5.68k
        }
22
5.68k
        self.composite_type.encode(sink);
23
5.68k
    }
24
}
25
26
#[cfg(feature = "wasmparser")]
27
impl TryFrom<wasmparser::SubType> for SubType {
28
    type Error = ();
29
30
    fn try_from(sub_ty: wasmparser::SubType) -> Result<Self, Self::Error> {
31
        Ok(SubType {
32
            is_final: sub_ty.is_final,
33
            supertype_idx: sub_ty
34
                .supertype_idx
35
                .map(|i| i.as_module_index().ok_or(()))
36
                .transpose()?,
37
            composite_type: sub_ty.composite_type.try_into()?,
38
        })
39
    }
40
}
41
42
/// Represents a composite type in a WebAssembly module.
43
#[derive(Debug, Clone)]
44
pub enum CompositeType {
45
    /// The type is for a function.
46
    Func(FuncType),
47
    /// The type is for an array.
48
    Array(ArrayType),
49
    /// The type is for a struct.
50
    Struct(StructType),
51
}
52
53
impl Encode for CompositeType {
54
5.68k
    fn encode(&self, sink: &mut Vec<u8>) {
55
5.68k
        match self {
56
5.68k
            CompositeType::Func(ty) => TypeSection::encode_function(
57
5.68k
                sink,
58
5.68k
                ty.params().iter().copied(),
59
5.68k
                ty.results().iter().copied(),
60
5.68k
            ),
61
0
            CompositeType::Array(ArrayType(ty)) => {
62
0
                TypeSection::encode_array(sink, &ty.element_type, ty.mutable)
63
            }
64
0
            CompositeType::Struct(ty) => {
65
0
                TypeSection::encode_struct(sink, ty.fields.iter().cloned())
66
            }
67
        }
68
5.68k
    }
69
}
70
71
#[cfg(feature = "wasmparser")]
72
impl TryFrom<wasmparser::CompositeType> for CompositeType {
73
    type Error = ();
74
    fn try_from(composite_ty: wasmparser::CompositeType) -> Result<Self, Self::Error> {
75
        Ok(match composite_ty {
76
            wasmparser::CompositeType::Func(f) => CompositeType::Func(f.try_into()?),
77
            wasmparser::CompositeType::Array(a) => CompositeType::Array(a.try_into()?),
78
            wasmparser::CompositeType::Struct(s) => CompositeType::Struct(s.try_into()?),
79
        })
80
    }
81
}
82
83
/// Represents a type of a function in a WebAssembly module.
84
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
85
pub struct FuncType {
86
    /// The combined parameters and result types.
87
    params_results: Box<[ValType]>,
88
    /// The number of parameter types.
89
    len_params: usize,
90
}
91
92
#[cfg(feature = "wasmparser")]
93
impl TryFrom<wasmparser::FuncType> for FuncType {
94
    type Error = ();
95
    fn try_from(func_ty: wasmparser::FuncType) -> Result<Self, Self::Error> {
96
        let mut buf = Vec::with_capacity(func_ty.params().len() + func_ty.results().len());
97
        for ty in func_ty.params().iter().chain(func_ty.results()).copied() {
98
            buf.push(ty.try_into()?);
99
        }
100
        Ok(FuncType::from_parts(buf.into(), func_ty.params().len()))
101
    }
102
}
103
104
/// Represents a type of an array in a WebAssembly module.
105
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
106
pub struct ArrayType(pub FieldType);
107
108
#[cfg(feature = "wasmparser")]
109
impl TryFrom<wasmparser::ArrayType> for ArrayType {
110
    type Error = ();
111
    fn try_from(array_ty: wasmparser::ArrayType) -> Result<Self, Self::Error> {
112
        Ok(ArrayType(array_ty.0.try_into()?))
113
    }
114
}
115
116
/// Represents a type of a struct in a WebAssembly module.
117
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
118
pub struct StructType {
119
    /// Struct fields.
120
    pub fields: Box<[FieldType]>,
121
}
122
123
#[cfg(feature = "wasmparser")]
124
impl TryFrom<wasmparser::StructType> for StructType {
125
    type Error = ();
126
    fn try_from(struct_ty: wasmparser::StructType) -> Result<Self, Self::Error> {
127
        Ok(StructType {
128
            fields: struct_ty
129
                .fields
130
                .iter()
131
                .cloned()
132
                .map(TryInto::try_into)
133
                .collect::<Result<_, _>>()?,
134
        })
135
    }
136
}
137
138
/// Field type in composite types (structs, arrays).
139
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
140
pub struct FieldType {
141
    /// Storage type of the field.
142
    pub element_type: StorageType,
143
    /// Is the field mutable.
144
    pub mutable: bool,
145
}
146
147
#[cfg(feature = "wasmparser")]
148
impl TryFrom<wasmparser::FieldType> for FieldType {
149
    type Error = ();
150
    fn try_from(field_ty: wasmparser::FieldType) -> Result<Self, Self::Error> {
151
        Ok(FieldType {
152
            element_type: field_ty.element_type.try_into()?,
153
            mutable: field_ty.mutable,
154
        })
155
    }
156
}
157
158
/// Storage type for composite type fields.
159
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
160
pub enum StorageType {
161
    /// The `i8` type.
162
    I8,
163
    /// The `i16` type.
164
    I16,
165
    /// A value type.
166
    Val(ValType),
167
}
168
169
#[cfg(feature = "wasmparser")]
170
impl TryFrom<wasmparser::StorageType> for StorageType {
171
    type Error = ();
172
    fn try_from(storage_ty: wasmparser::StorageType) -> Result<Self, Self::Error> {
173
        Ok(match storage_ty {
174
            wasmparser::StorageType::I8 => StorageType::I8,
175
            wasmparser::StorageType::I16 => StorageType::I16,
176
            wasmparser::StorageType::Val(v) => StorageType::Val(v.try_into()?),
177
        })
178
    }
179
}
180
181
impl StorageType {
182
    /// Is this storage type defaultable?
183
0
    pub fn is_defaultable(&self) -> bool {
184
0
        self.unpack().is_defaultable()
185
0
    }
Unexecuted instantiation: _RNvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_11StorageType14is_defaultableCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_11StorageType14is_defaultableB9_
186
187
    /// Unpack this storage type into a value type.
188
0
    pub fn unpack(&self) -> ValType {
189
0
        match self {
190
0
            StorageType::I8 | StorageType::I16 => ValType::I32,
191
0
            StorageType::Val(v) => *v,
192
        }
193
0
    }
Unexecuted instantiation: _RNvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_11StorageType6unpackCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs0_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_11StorageType6unpackB9_
194
}
195
196
/// The type of a core WebAssembly value.
197
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
198
pub enum ValType {
199
    /// The `i32` type.
200
    I32,
201
    /// The `i64` type.
202
    I64,
203
    /// The `f32` type.
204
    F32,
205
    /// The `f64` type.
206
    F64,
207
    /// The `v128` type.
208
    ///
209
    /// Part of the SIMD proposal.
210
    V128,
211
    /// A reference type.
212
    ///
213
    /// The `funcref` and `externref` type fall into this category and the full
214
    /// generalization here is due to the implementation of the
215
    /// function-references proposal.
216
    Ref(RefType),
217
}
218
219
#[cfg(feature = "wasmparser")]
220
impl TryFrom<wasmparser::ValType> for ValType {
221
    type Error = ();
222
    fn try_from(val_ty: wasmparser::ValType) -> Result<Self, Self::Error> {
223
        Ok(match val_ty {
224
            wasmparser::ValType::I32 => ValType::I32,
225
            wasmparser::ValType::I64 => ValType::I64,
226
            wasmparser::ValType::F32 => ValType::F32,
227
            wasmparser::ValType::F64 => ValType::F64,
228
            wasmparser::ValType::V128 => ValType::V128,
229
            wasmparser::ValType::Ref(r) => ValType::Ref(r.try_into()?),
230
        })
231
    }
232
}
233
234
impl ValType {
235
    /// Is this a numeric value type?
236
0
    pub fn is_numeric(&self) -> bool {
237
0
        match self {
238
0
            ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 => true,
239
0
            ValType::V128 | ValType::Ref(_) => false,
240
        }
241
0
    }
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_7ValType10is_numericCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_7ValType10is_numericB9_
242
243
    /// Is this a vector type?
244
0
    pub fn is_vector(&self) -> bool {
245
0
        match self {
246
0
            ValType::V128 => true,
247
0
            ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::Ref(_) => false,
248
        }
249
0
    }
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_7ValType9is_vectorCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs1_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_7ValType9is_vectorB9_
250
251
    /// Is this a reference type?
252
0
    pub fn is_reference(&self) -> bool {
253
0
        match self {
254
0
            ValType::Ref(_) => true,
255
0
            ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => false,
256
        }
257
0
    }
258
}
259
260
impl FuncType {
261
    /// Creates a new [`FuncType`] from the given `params` and `results`.
262
5.68k
    pub fn new<P, R>(params: P, results: R) -> Self
263
5.68k
    where
264
5.68k
        P: IntoIterator<Item = ValType>,
265
5.68k
        R: IntoIterator<Item = ValType>,
266
5.68k
    {
267
5.68k
        let mut buffer = params.into_iter().collect::<Vec<_>>();
268
5.68k
        let len_params = buffer.len();
269
5.68k
        buffer.extend(results);
270
5.68k
        Self::from_parts(buffer.into(), len_params)
271
5.68k
    }
_RINvMs2_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB6_8FuncType3newINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters6cloned6ClonedINtNtNtB1e_5slice4iter4IterNtB6_7ValTypeEEB15_ECs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
262
5.68k
    pub fn new<P, R>(params: P, results: R) -> Self
263
5.68k
    where
264
5.68k
        P: IntoIterator<Item = ValType>,
265
5.68k
        R: IntoIterator<Item = ValType>,
266
5.68k
    {
267
5.68k
        let mut buffer = params.into_iter().collect::<Vec<_>>();
268
5.68k
        let len_params = buffer.len();
269
5.68k
        buffer.extend(results);
270
5.68k
        Self::from_parts(buffer.into(), len_params)
271
5.68k
    }
Unexecuted instantiation: _RINvMs2_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB6_8FuncType3newppEBa_
272
273
    #[inline]
274
5.68k
    pub(crate) fn from_parts(params_results: Box<[ValType]>, len_params: usize) -> Self {
275
5.68k
        Self {
276
5.68k
            params_results,
277
5.68k
            len_params,
278
5.68k
        }
279
5.68k
    }
_RNvMs2_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_8FuncType10from_partsCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
274
5.68k
    pub(crate) fn from_parts(params_results: Box<[ValType]>, len_params: usize) -> Self {
275
5.68k
        Self {
276
5.68k
            params_results,
277
5.68k
            len_params,
278
5.68k
        }
279
5.68k
    }
Unexecuted instantiation: _RNvMs2_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_8FuncType10from_partsB9_
280
281
    /// Returns a shared slice to the parameter types of the [`FuncType`].
282
    #[inline]
283
5.68k
    pub fn params(&self) -> &[ValType] {
284
5.68k
        &self.params_results[..self.len_params]
285
5.68k
    }
286
287
    /// Returns a shared slice to the result types of the [`FuncType`].
288
    #[inline]
289
5.68k
    pub fn results(&self) -> &[ValType] {
290
5.68k
        &self.params_results[self.len_params..]
291
5.68k
    }
292
}
293
294
impl ValType {
295
    /// Alias for the `funcref` type in WebAssembly
296
    pub const FUNCREF: ValType = ValType::Ref(RefType::FUNCREF);
297
    /// Alias for the `externref` type in WebAssembly
298
    pub const EXTERNREF: ValType = ValType::Ref(RefType::EXTERNREF);
299
    /// Alias for the `exnref` type in WebAssembly
300
    pub const EXNREF: ValType = ValType::Ref(RefType::EXNREF);
301
302
    /// Is this value defaultable?
303
0
    pub fn is_defaultable(&self) -> bool {
304
0
        match self {
305
0
            ValType::Ref(r) => r.nullable,
306
0
            ValType::I32 | ValType::I64 | ValType::F32 | ValType::F64 | ValType::V128 => true,
307
        }
308
0
    }
Unexecuted instantiation: _RNvMs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_7ValType14is_defaultableCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvMs3_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_7ValType14is_defaultableB9_
309
}
310
311
impl Encode for StorageType {
312
0
    fn encode(&self, sink: &mut Vec<u8>) {
313
0
        match self {
314
0
            StorageType::I8 => sink.push(0x78),
315
0
            StorageType::I16 => sink.push(0x77),
316
0
            StorageType::Val(vt) => vt.encode(sink),
317
        }
318
0
    }
319
}
320
321
impl Encode for ValType {
322
17.2k
    fn encode(&self, sink: &mut Vec<u8>) {
323
17.2k
        match self {
324
10.6k
            ValType::I32 => sink.push(0x7F),
325
3.06k
            ValType::I64 => sink.push(0x7E),
326
2.03k
            ValType::F32 => sink.push(0x7D),
327
1.49k
            ValType::F64 => sink.push(0x7C),
328
0
            ValType::V128 => sink.push(0x7B),
329
0
            ValType::Ref(rt) => rt.encode(sink),
330
        }
331
17.2k
    }
332
}
333
334
/// A reference type.
335
///
336
/// This is largely part of the function references proposal for WebAssembly but
337
/// additionally is used by the `funcref` and `externref` types. The full
338
/// generality of this type is only exercised with function-references.
339
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
340
#[allow(missing_docs)]
341
pub struct RefType {
342
    pub nullable: bool,
343
    pub heap_type: HeapType,
344
}
345
346
impl RefType {
347
    /// Alias for the `funcref` type in WebAssembly
348
    pub const FUNCREF: RefType = RefType {
349
        nullable: true,
350
        heap_type: HeapType::Func,
351
    };
352
353
    /// Alias for the `externref` type in WebAssembly
354
    pub const EXTERNREF: RefType = RefType {
355
        nullable: true,
356
        heap_type: HeapType::Extern,
357
    };
358
359
    /// Alias for the `exnref` type in WebAssembly
360
    pub const EXNREF: RefType = RefType {
361
        nullable: true,
362
        heap_type: HeapType::Exn,
363
    };
364
}
365
366
impl Encode for RefType {
367
1.32k
    fn encode(&self, sink: &mut Vec<u8>) {
368
1.32k
        if self.nullable {
369
            // Favor the original encodings of `funcref` and `externref` where
370
            // possible
371
1.32k
            match self.heap_type {
372
1.32k
                HeapType::Func => return sink.push(0x70),
373
0
                HeapType::Extern => return sink.push(0x6f),
374
0
                _ => {}
375
            }
376
0
        }
377
378
0
        if self.nullable {
379
0
            sink.push(0x63);
380
0
        } else {
381
0
            sink.push(0x64);
382
0
        }
383
0
        self.heap_type.encode(sink);
384
1.32k
    }
385
}
386
387
#[cfg(feature = "wasmparser")]
388
impl TryFrom<wasmparser::RefType> for RefType {
389
    type Error = ();
390
391
    fn try_from(ref_type: wasmparser::RefType) -> Result<Self, Self::Error> {
392
        Ok(RefType {
393
            nullable: ref_type.is_nullable(),
394
            heap_type: ref_type.heap_type().try_into()?,
395
        })
396
    }
397
}
398
399
impl From<RefType> for ValType {
400
2.65k
    fn from(ty: RefType) -> ValType {
401
2.65k
        ValType::Ref(ty)
402
2.65k
    }
_RNvXs8_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_7ValTypeINtNtCs1ujR1JRCAmI_4core7convert4FromNtB5_7RefTypeE4fromCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
400
2.65k
    fn from(ty: RefType) -> ValType {
401
2.65k
        ValType::Ref(ty)
402
2.65k
    }
Unexecuted instantiation: _RNvXs8_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_7ValTypeINtNtCs1ujR1JRCAmI_4core7convert4FromNtB5_7RefTypeE4fromB9_
403
}
404
405
/// Part of the function references proposal.
406
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Ord, PartialOrd)]
407
pub enum HeapType {
408
    /// Untyped (any) function.
409
    Func,
410
411
    /// The abstract external heap type.
412
    Extern,
413
414
    /// The abstract `any` heap type.
415
    ///
416
    /// The common supertype (a.k.a. top) of all internal types.
417
    Any,
418
419
    /// The abstract `none` heap type.
420
    ///
421
    /// The common subtype (a.k.a. bottom) of all internal types.
422
    None,
423
424
    /// The abstract `noextern` heap type.
425
    ///
426
    /// The common subtype (a.k.a. bottom) of all external types.
427
    NoExtern,
428
429
    /// The abstract `nofunc` heap type.
430
    ///
431
    /// The common subtype (a.k.a. bottom) of all function types.
432
    NoFunc,
433
434
    /// The abstract `eq` heap type.
435
    ///
436
    /// The common supertype of all referenceable types on which comparison
437
    /// (ref.eq) is allowed.
438
    Eq,
439
440
    /// The abstract `struct` heap type.
441
    ///
442
    /// The common supertype of all struct types.
443
    Struct,
444
445
    /// The abstract `array` heap type.
446
    ///
447
    /// The common supertype of all array types.
448
    Array,
449
450
    /// The unboxed `i31` heap type.
451
    I31,
452
453
    /// The abstract `exception` heap type.
454
    Exn,
455
456
    /// The abstract `noexn` heap type.
457
    NoExn,
458
459
    /// A concrete Wasm-defined type at the given index.
460
    Concrete(u32),
461
}
462
463
impl Encode for HeapType {
464
0
    fn encode(&self, sink: &mut Vec<u8>) {
465
0
        match self {
466
0
            HeapType::Func => sink.push(0x70),
467
0
            HeapType::Extern => sink.push(0x6F),
468
0
            HeapType::Any => sink.push(0x6E),
469
0
            HeapType::None => sink.push(0x71),
470
0
            HeapType::NoExtern => sink.push(0x72),
471
0
            HeapType::NoFunc => sink.push(0x73),
472
0
            HeapType::Eq => sink.push(0x6D),
473
0
            HeapType::Struct => sink.push(0x6B),
474
0
            HeapType::Array => sink.push(0x6A),
475
0
            HeapType::I31 => sink.push(0x6C),
476
0
            HeapType::Exn => sink.push(0x69),
477
0
            HeapType::NoExn => sink.push(0x74),
478
            // Note that this is encoded as a signed type rather than unsigned
479
            // as it's decoded as an s33
480
0
            HeapType::Concrete(i) => i64::from(*i).encode(sink),
481
        }
482
0
    }
483
}
484
485
#[cfg(feature = "wasmparser")]
486
impl TryFrom<wasmparser::HeapType> for HeapType {
487
    type Error = ();
488
489
    fn try_from(heap_type: wasmparser::HeapType) -> Result<Self, Self::Error> {
490
        Ok(match heap_type {
491
            wasmparser::HeapType::Concrete(i) => HeapType::Concrete(i.as_module_index().ok_or(())?),
492
            wasmparser::HeapType::Func => HeapType::Func,
493
            wasmparser::HeapType::Extern => HeapType::Extern,
494
            wasmparser::HeapType::Any => HeapType::Any,
495
            wasmparser::HeapType::None => HeapType::None,
496
            wasmparser::HeapType::NoExtern => HeapType::NoExtern,
497
            wasmparser::HeapType::NoFunc => HeapType::NoFunc,
498
            wasmparser::HeapType::Eq => HeapType::Eq,
499
            wasmparser::HeapType::Struct => HeapType::Struct,
500
            wasmparser::HeapType::Array => HeapType::Array,
501
            wasmparser::HeapType::I31 => HeapType::I31,
502
            wasmparser::HeapType::Exn => HeapType::Exn,
503
            wasmparser::HeapType::NoExn => HeapType::NoExn,
504
        })
505
    }
506
}
507
508
/// An encoder for the type section of WebAssembly modules.
509
///
510
/// # Example
511
///
512
/// ```rust
513
/// use wasm_encoder::{Module, TypeSection, ValType};
514
///
515
/// let mut types = TypeSection::new();
516
///
517
/// types.function([ValType::I32, ValType::I32], [ValType::I64]);
518
///
519
/// let mut module = Module::new();
520
/// module.section(&types);
521
///
522
/// let bytes = module.finish();
523
/// ```
524
#[derive(Clone, Debug, Default)]
525
pub struct TypeSection {
526
    bytes: Vec<u8>,
527
    num_added: u32,
528
}
529
530
impl TypeSection {
531
    /// Create a new module type section encoder.
532
4.63k
    pub fn new() -> Self {
533
4.63k
        Self::default()
534
4.63k
    }
_RNvMsa_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_11TypeSection3newCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
532
4.63k
    pub fn new() -> Self {
533
4.63k
        Self::default()
534
4.63k
    }
Unexecuted instantiation: _RNvMsa_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_11TypeSection3newB9_
535
536
    /// The number of types in the section.
537
0
    pub fn len(&self) -> u32 {
538
0
        self.num_added
539
0
    }
540
541
    /// Determines if the section is empty.
542
0
    pub fn is_empty(&self) -> bool {
543
0
        self.num_added == 0
544
0
    }
545
546
    /// Define a function type in this type section.
547
0
    pub fn function<P, R>(&mut self, params: P, results: R) -> &mut Self
548
0
    where
549
0
        P: IntoIterator<Item = ValType>,
550
0
        P::IntoIter: ExactSizeIterator,
551
0
        R: IntoIterator<Item = ValType>,
552
0
        R::IntoIter: ExactSizeIterator,
553
0
    {
554
0
        Self::encode_function(&mut self.bytes, params, results);
555
0
        self.num_added += 1;
556
0
        self
557
0
    }
558
559
5.68k
    fn encode_function<P, R>(sink: &mut Vec<u8>, params: P, results: R)
560
5.68k
    where
561
5.68k
        P: IntoIterator<Item = ValType>,
562
5.68k
        P::IntoIter: ExactSizeIterator,
563
5.68k
        R: IntoIterator<Item = ValType>,
564
5.68k
        R::IntoIter: ExactSizeIterator,
565
5.68k
    {
566
5.68k
        let params = params.into_iter();
567
5.68k
        let results = results.into_iter();
568
5.68k
569
5.68k
        sink.push(0x60);
570
5.68k
        params.len().encode(sink);
571
5.68k
        params.for_each(|p| p.encode(sink));
572
5.68k
        results.len().encode(sink);
573
5.68k
        results.for_each(|p| p.encode(sink));
574
5.68k
    }
575
576
    /// Define an array type in this type section.
577
0
    pub fn array(&mut self, ty: &StorageType, mutable: bool) -> &mut Self {
578
0
        Self::encode_array(&mut self.bytes, ty, mutable);
579
0
        self.num_added += 1;
580
0
        self
581
0
    }
582
583
0
    fn encode_array(sink: &mut Vec<u8>, ty: &StorageType, mutable: bool) {
584
0
        sink.push(0x5e);
585
0
        Self::encode_field(sink, ty, mutable);
586
0
    }
587
588
0
    fn encode_field(sink: &mut Vec<u8>, ty: &StorageType, mutable: bool) {
589
0
        ty.encode(sink);
590
0
        sink.push(mutable as u8);
591
0
    }
592
593
    /// Define a struct type in this type section.
594
0
    pub fn struct_<F>(&mut self, fields: F) -> &mut Self
595
0
    where
596
0
        F: IntoIterator<Item = FieldType>,
597
0
        F::IntoIter: ExactSizeIterator,
598
0
    {
599
0
        Self::encode_struct(&mut self.bytes, fields);
600
0
        self.num_added += 1;
601
0
        self
602
0
    }
603
604
0
    fn encode_struct<F>(sink: &mut Vec<u8>, fields: F)
605
0
    where
606
0
        F: IntoIterator<Item = FieldType>,
607
0
        F::IntoIter: ExactSizeIterator,
608
0
    {
609
0
        let fields = fields.into_iter();
610
0
        sink.push(0x5f);
611
0
        fields.len().encode(sink);
612
0
        for f in fields {
613
0
            Self::encode_field(sink, &f.element_type, f.mutable);
614
0
        }
615
0
    }
616
617
    /// Define an explicit subtype in this type section.
618
5.68k
    pub fn subtype(&mut self, ty: &SubType) -> &mut Self {
619
5.68k
        ty.encode(&mut self.bytes);
620
5.68k
        self.num_added += 1;
621
5.68k
        self
622
5.68k
    }
623
624
    /// Define an explicit recursion group in this type section.
625
0
    pub fn rec<T>(&mut self, types: T) -> &mut Self
626
0
    where
627
0
        T: IntoIterator<Item = SubType>,
628
0
        T::IntoIter: ExactSizeIterator,
629
0
    {
630
0
        let types = types.into_iter();
631
0
        self.bytes.push(0x4e);
632
0
        types.len().encode(&mut self.bytes);
633
0
        types.for_each(|t| t.encode(&mut self.bytes));
Unexecuted instantiation: _RNCINvMsa_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB8_11TypeSection3recINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1k_5slice4iter4IterNtNtCs4eJdYXiOSk9_10wasm_smith4core7SubTypeENCNvMNtB2s_6encodeNtB2s_6Module12encode_types0EE0B2u_
Unexecuted instantiation: _RNCINvMsa_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB8_11TypeSection3recpE0Bc_
634
0
        self.num_added += 1;
635
0
        self
636
0
    }
Unexecuted instantiation: _RINvMsa_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB6_11TypeSection3recINtNtNtNtCs1ujR1JRCAmI_4core4iter8adapters3map3MapINtNtNtB1i_5slice4iter4IterNtNtCs4eJdYXiOSk9_10wasm_smith4core7SubTypeENCNvMNtB2q_6encodeNtB2q_6Module12encode_types0EEB2s_
Unexecuted instantiation: _RINvMsa_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB6_11TypeSection3recpEBa_
637
}
638
639
impl Encode for TypeSection {
640
4.63k
    fn encode(&self, sink: &mut Vec<u8>) {
641
4.63k
        encode_section(sink, self.num_added, &self.bytes);
642
4.63k
    }
643
}
644
645
impl Section for TypeSection {
646
4.63k
    fn id(&self) -> u8 {
647
4.63k
        SectionId::Type.into()
648
4.63k
    }
_RNvXsc_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_11TypeSectionNtB7_7Section2idCs4eJdYXiOSk9_10wasm_smith
Line
Count
Source
646
4.63k
    fn id(&self) -> u8 {
647
4.63k
        SectionId::Type.into()
648
4.63k
    }
Unexecuted instantiation: _RNvXsc_NtNtCs5Pk8z11FdwQ_12wasm_encoder4core5typesNtB5_11TypeSectionNtB7_7Section2idB9_
649
}
650
651
#[cfg(test)]
652
mod tests {
653
    use wasmparser::WasmFeatures;
654
655
    use super::*;
656
    use crate::Module;
657
658
    #[test]
659
    fn func_types_dont_require_wasm_gc() {
660
        let mut types = TypeSection::new();
661
        types.subtype(&SubType {
662
            is_final: true,
663
            supertype_idx: None,
664
            composite_type: CompositeType::Func(FuncType::new([], [])),
665
        });
666
667
        let mut module = Module::new();
668
        module.section(&types);
669
        let wasm_bytes = module.finish();
670
671
        let mut validator =
672
            wasmparser::Validator::new_with_features(WasmFeatures::default() & !WasmFeatures::GC);
673
674
        validator.validate_all(&wasm_bytes).expect(
675
            "Encoding pre Wasm GC type should not accidentally use Wasm GC specific encoding",
676
        );
677
    }
678
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! A WebAssembly encoder.
2
//!
3
//! The main builder is the [`Module`]. You can build a section with a
4
//! section-specific builder, like [`TypeSection`] or [`ImportSection`], and
5
//! then add it to the module with [`Module::section`]. When you are finished
6
//! building the module, call either [`Module::as_slice`] or [`Module::finish`]
7
//! to get the encoded bytes. The former gives a shared reference to the
8
//! underlying bytes as a slice, while the latter gives you ownership of them as
9
//! a vector.
10
//!
11
//! # Example
12
//!
13
//! If we wanted to build this module:
14
//!
15
//! ```wasm
16
//! (module
17
//!   (type (func (param i32 i32) (result i32)))
18
//!   (func (type 0)
19
//!     local.get 0
20
//!     local.get 1
21
//!     i32.add)
22
//!   (export "f" (func 0)))
23
//! ```
24
//!
25
//! then we would do this:
26
//!
27
//! ```
28
//! use wasm_encoder::{
29
//!     CodeSection, ExportKind, ExportSection, Function, FunctionSection, Instruction,
30
//!     Module, TypeSection, ValType,
31
//! };
32
//!
33
//! let mut module = Module::new();
34
//!
35
//! // Encode the type section.
36
//! let mut types = TypeSection::new();
37
//! let params = vec![ValType::I32, ValType::I32];
38
//! let results = vec![ValType::I32];
39
//! types.function(params, results);
40
//! module.section(&types);
41
//!
42
//! // Encode the function section.
43
//! let mut functions = FunctionSection::new();
44
//! let type_index = 0;
45
//! functions.function(type_index);
46
//! module.section(&functions);
47
//!
48
//! // Encode the export section.
49
//! let mut exports = ExportSection::new();
50
//! exports.export("f", ExportKind::Func, 0);
51
//! module.section(&exports);
52
//!
53
//! // Encode the code section.
54
//! let mut codes = CodeSection::new();
55
//! let locals = vec![];
56
//! let mut f = Function::new(locals);
57
//! f.instruction(&Instruction::LocalGet(0));
58
//! f.instruction(&Instruction::LocalGet(1));
59
//! f.instruction(&Instruction::I32Add);
60
//! f.instruction(&Instruction::End);
61
//! codes.function(&f);
62
//! module.section(&codes);
63
//!
64
//! // Extract the encoded Wasm bytes for this module.
65
//! let wasm_bytes = module.finish();
66
//!
67
//! // We generated a valid Wasm module!
68
//! assert!(wasmparser::validate(&wasm_bytes).is_ok());
69
//! ```
70
71
#![deny(missing_docs, missing_debug_implementations)]
72
73
mod component;
74
mod core;
75
mod raw;
76
77
pub use self::component::*;
78
pub use self::core::*;
79
pub use self::raw::*;
80
81
/// Implemented by types that can be encoded into a byte sink.
82
pub trait Encode {
83
    /// Encode the type into the given byte sink.
84
    fn encode(&self, sink: &mut Vec<u8>);
85
}
86
87
impl<T: Encode + ?Sized> Encode for &'_ T {
88
1.58k
    fn encode(&self, sink: &mut Vec<u8>) {
89
1.58k
        T::encode(self, sink)
90
1.58k
    }
Unexecuted instantiation: _RNvXCs5Pk8z11FdwQ_12wasm_encoderReNtB2_6Encode6encodeB2_
_RNvXCs5Pk8z11FdwQ_12wasm_encoderRNtNtNtB2_4core4code9ConstExprNtB2_6Encode6encodeB2_
Line
Count
Source
88
1.58k
    fn encode(&self, sink: &mut Vec<u8>) {
89
1.58k
        T::encode(self, sink)
90
1.58k
    }
91
}
92
93
impl<T: Encode> Encode for [T] {
94
2.31k
    fn encode(&self, sink: &mut Vec<u8>) {
95
2.31k
        self.len().encode(sink);
96
7.20k
        for item in self {
97
4.88k
            item.encode(sink);
98
4.88k
        }
99
2.31k
    }
Unexecuted instantiation: _RNvXs_Cs5Pk8z11FdwQ_12wasm_encoderSNtNtNtB4_4core4code5CatchNtB4_6Encode6encodeB4_
Unexecuted instantiation: _RNvXs_Cs5Pk8z11FdwQ_12wasm_encoderSNtNtNtB4_4core5types7ValTypeNtB4_6Encode6encodeB4_
_RNvXs_Cs5Pk8z11FdwQ_12wasm_encoderSmNtB4_6Encode6encodeB4_
Line
Count
Source
94
2.31k
    fn encode(&self, sink: &mut Vec<u8>) {
95
2.31k
        self.len().encode(sink);
96
7.20k
        for item in self {
97
4.88k
            item.encode(sink);
98
4.88k
        }
99
2.31k
    }
100
}
101
102
impl Encode for [u8] {
103
15.8k
    fn encode(&self, sink: &mut Vec<u8>) {
104
15.8k
        self.len().encode(sink);
105
15.8k
        sink.extend(self);
106
15.8k
    }
107
}
108
109
impl Encode for str {
110
14.1k
    fn encode(&self, sink: &mut Vec<u8>) {
111
14.1k
        self.len().encode(sink);
112
14.1k
        sink.extend_from_slice(self.as_bytes());
113
14.1k
    }
114
}
115
116
impl Encode for usize {
117
81.5k
    fn encode(&self, sink: &mut Vec<u8>) {
118
81.5k
        assert!(*self <= u32::max_value() as usize);
119
81.5k
        (*self as u32).encode(sink)
120
81.5k
    }
121
}
122
123
impl Encode for u32 {
124
163k
    fn encode(&self, sink: &mut Vec<u8>) {
125
163k
        leb128::write::unsigned(sink, (*self).into()).unwrap();
126
163k
    }
127
}
128
129
impl Encode for i32 {
130
8.04k
    fn encode(&self, sink: &mut Vec<u8>) {
131
8.04k
        leb128::write::signed(sink, (*self).into()).unwrap();
132
8.04k
    }
133
}
134
135
impl Encode for u64 {
136
8.07k
    fn encode(&self, sink: &mut Vec<u8>) {
137
8.07k
        leb128::write::unsigned(sink, *self).unwrap();
138
8.07k
    }
139
}
140
141
impl Encode for i64 {
142
5.44k
    fn encode(&self, sink: &mut Vec<u8>) {
143
5.44k
        leb128::write::signed(sink, *self).unwrap();
144
5.44k
    }
145
}
146
147
impl Encode for f32 {
148
0
    fn encode(&self, sink: &mut Vec<u8>) {
149
0
        let bits = self.to_bits();
150
0
        sink.extend(bits.to_le_bytes())
151
0
    }
152
}
153
154
impl Encode for f64 {
155
0
    fn encode(&self, sink: &mut Vec<u8>) {
156
0
        let bits = self.to_bits();
157
0
        sink.extend(bits.to_le_bytes())
158
0
    }
159
}
160
161
0
fn encode_vec<T, V>(elements: V, sink: &mut Vec<u8>)
162
0
where
163
0
    T: Encode,
164
0
    V: IntoIterator<Item = T>,
165
0
    V::IntoIter: ExactSizeIterator,
166
0
{
167
0
    let elements = elements.into_iter();
168
0
    u32::try_from(elements.len()).unwrap().encode(sink);
169
0
    for x in elements {
170
0
        x.encode(sink);
171
0
    }
172
0
}
173
174
impl<T> Encode for Option<T>
175
where
176
    T: Encode,
177
{
178
0
    fn encode(&self, sink: &mut Vec<u8>) {
179
0
        match self {
180
0
            Some(v) => {
181
0
                sink.push(0x01);
182
0
                v.encode(sink);
183
0
            }
184
0
            None => sink.push(0x00),
185
        }
186
0
    }
Unexecuted instantiation: _RNvXs9_Cs5Pk8z11FdwQ_12wasm_encoderINtNtCs1ujR1JRCAmI_4core6option6OptionNtNtNtB5_9component5types16ComponentValTypeENtB5_6Encode6encodeCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs9_Cs5Pk8z11FdwQ_12wasm_encoderINtNtCs1ujR1JRCAmI_4core6option6OptionmENtB5_6Encode6encodeCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs9_Cs5Pk8z11FdwQ_12wasm_encoderINtNtCs1ujR1JRCAmI_4core6option6OptionNtNtNtB5_9component5types16ComponentValTypeENtB5_6Encode6encodeB5_
Unexecuted instantiation: _RNvXs9_Cs5Pk8z11FdwQ_12wasm_encoderINtNtCs1ujR1JRCAmI_4core6option6OptionmENtB5_6Encode6encodeB5_
187
}
188
189
21.4k
fn encoding_size(n: u32) -> usize {
190
21.4k
    let mut buf = [0u8; 5];
191
21.4k
    leb128::write::unsigned(&mut &mut buf[..], n.into()).unwrap()
192
21.4k
}
193
194
20.8k
fn encode_section(sink: &mut Vec<u8>, count: u32, bytes: &[u8]) {
195
20.8k
    (encoding_size(count) + bytes.len()).encode(sink);
196
20.8k
    count.encode(sink);
197
20.8k
    sink.extend(bytes);
198
20.8k
}
199
200
#[cfg(test)]
201
mod test {
202
    use super::*;
203
204
    #[test]
205
    fn it_encodes_an_empty_module() {
206
        let bytes = Module::new().finish();
207
        assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x01, 0x00, 0x00, 0x00]);
208
    }
209
210
    #[test]
211
    fn it_encodes_an_empty_component() {
212
        let bytes = Component::new().finish();
213
        assert_eq!(bytes, [0x00, b'a', b's', b'm', 0x0d, 0x00, 0x01, 0x00]);
214
    }
215
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-encoder-0.210.0/src/raw.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::{ComponentSection, Encode, Section};
2
3
/// A section made up of uninterpreted, raw bytes.
4
///
5
/// Allows you to splat any data into a module or component.
6
#[derive(Clone, Copy, Debug)]
7
pub struct RawSection<'a> {
8
    /// The id for this section.
9
    pub id: u8,
10
    /// The raw data for this section.
11
    pub data: &'a [u8],
12
}
13
14
impl Encode for RawSection<'_> {
15
0
    fn encode(&self, sink: &mut Vec<u8>) {
16
0
        self.data.encode(sink);
17
0
    }
18
}
19
20
impl Section for RawSection<'_> {
21
0
    fn id(&self) -> u8 {
22
0
        self.id
23
0
    }
24
}
25
26
impl ComponentSection for RawSection<'_> {
27
0
    fn id(&self) -> u8 {
28
0
        self.id
29
0
    }
Unexecuted instantiation: _RNvXs0_NtCs5Pk8z11FdwQ_12wasm_encoder3rawNtB5_10RawSectionNtNtB7_9component16ComponentSection2idCs4eJdYXiOSk9_10wasm_smith
Unexecuted instantiation: _RNvXs0_NtCs5Pk8z11FdwQ_12wasm_encoder3rawNtB5_10RawSectionNtNtB7_9component16ComponentSection2idB7_
30
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/component.rs
Line
Count
Source (jump to first uncovered line)
1
//! Generation of Wasm
2
//! [components](https://github.com/WebAssembly/component-model).
3
4
// FIXME(#1000): component support in `wasm-smith` is a work in progress.
5
#![allow(unused_variables, dead_code)]
6
7
use crate::{arbitrary_loop, Config};
8
use arbitrary::{Arbitrary, Result, Unstructured};
9
use std::collections::BTreeMap;
10
use std::{
11
    collections::{HashMap, HashSet},
12
    rc::Rc,
13
};
14
use wasm_encoder::{
15
    ComponentTypeRef, ComponentValType, HeapType, PrimitiveValType, RefType, TypeBounds, ValType,
16
};
17
18
mod encode;
19
20
/// A pseudo-random WebAssembly [component].
21
///
22
/// Construct instances of this type with [the `Arbitrary`
23
/// trait](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html).
24
///
25
/// [component]: https://github.com/WebAssembly/component-model/blob/ast-and-binary/design/MVP/Explainer.md
26
///
27
/// ## Configured Generated Components
28
///
29
/// The `Arbitrary` implementation uses the [`Config::default()`][crate::Config]
30
/// configuration. If you want to customize the shape of generated components,
31
/// create your own [`Config`][crate::Config] instance and pass it to
32
/// [`Component::new`][crate::Component::new].
33
#[derive(Debug)]
34
pub struct Component {
35
    sections: Vec<Section>,
36
}
37
38
/// A builder to create a component (and possibly a whole tree of nested
39
/// components).
40
///
41
/// Maintains a stack of components we are currently building, as well as
42
/// metadata about them. The split between `Component` and `ComponentBuilder` is
43
/// that the builder contains metadata that is purely used when generating
44
/// components and is unnecessary after we are done generating the structure of
45
/// the components and only need to encode an already-generated component to
46
/// bytes.
47
#[derive(Debug)]
48
struct ComponentBuilder {
49
    config: Config,
50
51
    // The set of core `valtype`s that we are configured to generate.
52
    core_valtypes: Vec<ValType>,
53
54
    // Stack of types scopes that are currently available.
55
    //
56
    // There is an entry in this stack for each component, but there can also be
57
    // additional entries for module/component/instance types, each of which
58
    // have their own scope.
59
    //
60
    // This stack is always non-empty and the last entry is always the current
61
    // scope.
62
    //
63
    // When a particular scope can alias outer types, it can alias from any
64
    // scope that is older than it (i.e. `types_scope[i]` can alias from
65
    // `types_scope[j]` when `j <= i`).
66
    types: Vec<TypesScope>,
67
68
    // The set of components we are currently building and their associated
69
    // metadata.
70
    components: Vec<ComponentContext>,
71
72
    // Whether we are in the final bits of generating this component and we just
73
    // need to ensure that the minimum number of entities configured have all
74
    // been generated. This changes the behavior of various
75
    // `arbitrary_<section>` methods to always fill in their minimums.
76
    fill_minimums: bool,
77
78
    // Our maximums for these entities are applied across the whole component
79
    // tree, not per-component.
80
    total_components: usize,
81
    total_modules: usize,
82
    total_instances: usize,
83
    total_values: usize,
84
}
85
86
#[derive(Debug, Clone)]
87
enum ComponentOrCoreFuncType {
88
    Component(Rc<FuncType>),
89
    Core(Rc<crate::core::FuncType>),
90
}
91
92
impl ComponentOrCoreFuncType {
93
0
    fn as_core(&self) -> &Rc<crate::core::FuncType> {
94
0
        match self {
95
0
            ComponentOrCoreFuncType::Core(t) => t,
96
0
            ComponentOrCoreFuncType::Component(_) => panic!("not a core func type"),
97
        }
98
0
    }
99
100
0
    fn as_component(&self) -> &Rc<FuncType> {
101
0
        match self {
102
0
            ComponentOrCoreFuncType::Core(_) => panic!("not a component func type"),
103
0
            ComponentOrCoreFuncType::Component(t) => t,
104
0
        }
105
0
    }
106
}
107
108
#[derive(Debug, Clone)]
109
enum ComponentOrCoreInstanceType {
110
    Component(Rc<InstanceType>),
111
    Core(BTreeMap<String, crate::core::EntityType>),
112
}
113
114
/// Metadata (e.g. contents of various index spaces) we keep track of on a
115
/// per-component basis.
116
#[derive(Debug)]
117
struct ComponentContext {
118
    // The actual component itself.
119
    component: Component,
120
121
    // The number of imports we have generated thus far.
122
    num_imports: usize,
123
124
    // The set of names of imports we've generated thus far.
125
    import_names: HashSet<String>,
126
127
    // The set of URLs of imports we've generated thus far.
128
    import_urls: HashSet<String>,
129
130
    // This component's function index space.
131
    funcs: Vec<ComponentOrCoreFuncType>,
132
133
    // Which entries in `funcs` are component functions?
134
    component_funcs: Vec<u32>,
135
136
    // Which entries in `component_funcs` are component functions that only use scalar
137
    // types?
138
    scalar_component_funcs: Vec<u32>,
139
140
    // Which entries in `funcs` are core Wasm functions?
141
    //
142
    // Note that a component can't import core functions, so these entries will
143
    // never point to a `Section::Import`.
144
    core_funcs: Vec<u32>,
145
146
    // This component's component index space.
147
    //
148
    // An indirect list of all directly-nested (not transitive) components
149
    // inside this component.
150
    //
151
    // Each entry is of the form `(i, j)` where `component.sections[i]` is
152
    // guaranteed to be either
153
    //
154
    // * a `Section::Component` and we are referencing the component defined in
155
    //   that section (in this case `j` must also be `0`, since a component
156
    //   section can only contain a single nested component), or
157
    //
158
    // * a `Section::Import` and we are referencing the `j`th import in that
159
    //   section, which is guaranteed to be a component import.
160
    components: Vec<(usize, usize)>,
161
162
    // This component's module index space.
163
    //
164
    // An indirect list of all directly-nested (not transitive) modules
165
    // inside this component.
166
    //
167
    // Each entry is of the form `(i, j)` where `component.sections[i]` is
168
    // guaranteed to be either
169
    //
170
    // * a `Section::Core` and we are referencing the module defined in that
171
    //   section (in this case `j` must also be `0`, since a core section can
172
    //   only contain a single nested module), or
173
    //
174
    // * a `Section::Import` and we are referencing the `j`th import in that
175
    //   section, which is guaranteed to be a module import.
176
    modules: Vec<(usize, usize)>,
177
178
    // This component's instance index space.
179
    instances: Vec<ComponentOrCoreInstanceType>,
180
181
    // This component's value index space.
182
    values: Vec<ComponentValType>,
183
}
184
185
impl ComponentContext {
186
0
    fn empty() -> Self {
187
0
        ComponentContext {
188
0
            component: Component::empty(),
189
0
            num_imports: 0,
190
0
            import_names: HashSet::default(),
191
0
            import_urls: HashSet::default(),
192
0
            funcs: vec![],
193
0
            component_funcs: vec![],
194
0
            scalar_component_funcs: vec![],
195
0
            core_funcs: vec![],
196
0
            components: vec![],
197
0
            modules: vec![],
198
0
            instances: vec![],
199
0
            values: vec![],
200
0
        }
201
0
    }
202
203
0
    fn num_modules(&self) -> usize {
204
0
        self.modules.len()
205
0
    }
206
207
0
    fn num_components(&self) -> usize {
208
0
        self.components.len()
209
0
    }
210
211
0
    fn num_instances(&self) -> usize {
212
0
        self.instances.len()
213
0
    }
214
215
0
    fn num_funcs(&self) -> usize {
216
0
        self.funcs.len()
217
0
    }
218
219
0
    fn num_values(&self) -> usize {
220
0
        self.values.len()
221
0
    }
222
}
223
224
#[derive(Debug, Default)]
225
struct TypesScope {
226
    // All core types in this scope, regardless of kind.
227
    core_types: Vec<Rc<CoreType>>,
228
229
    // The indices of all the entries in `core_types` that are core function types.
230
    core_func_types: Vec<u32>,
231
232
    // The indices of all the entries in `core_types` that are module types.
233
    module_types: Vec<u32>,
234
235
    // All component types in this index space, regardless of kind.
236
    types: Vec<Rc<Type>>,
237
238
    // The indices of all the entries in `types` that are defined value types.
239
    defined_types: Vec<u32>,
240
241
    // The indices of all the entries in `types` that are func types.
242
    func_types: Vec<u32>,
243
244
    // A map from function types to their indices in the types space.
245
    func_type_to_indices: HashMap<Rc<FuncType>, Vec<u32>>,
246
247
    // The indices of all the entries in `types` that are component types.
248
    component_types: Vec<u32>,
249
250
    // The indices of all the entries in `types` that are instance types.
251
    instance_types: Vec<u32>,
252
}
253
254
impl TypesScope {
255
0
    fn push(&mut self, ty: Rc<Type>) -> u32 {
256
0
        let ty_idx = u32::try_from(self.types.len()).unwrap();
257
258
0
        let kind_list = match &*ty {
259
0
            Type::Defined(_) => &mut self.defined_types,
260
0
            Type::Func(func_ty) => {
261
0
                self.func_type_to_indices
262
0
                    .entry(func_ty.clone())
263
0
                    .or_default()
264
0
                    .push(ty_idx);
265
0
                &mut self.func_types
266
            }
267
0
            Type::Component(_) => &mut self.component_types,
268
0
            Type::Instance(_) => &mut self.instance_types,
269
        };
270
0
        kind_list.push(ty_idx);
271
0
272
0
        self.types.push(ty);
273
0
        ty_idx
274
0
    }
275
276
0
    fn push_core(&mut self, ty: Rc<CoreType>) -> u32 {
277
0
        let ty_idx = u32::try_from(self.core_types.len()).unwrap();
278
279
0
        let kind_list = match &*ty {
280
0
            CoreType::Func(_) => &mut self.core_func_types,
281
0
            CoreType::Module(_) => &mut self.module_types,
282
        };
283
0
        kind_list.push(ty_idx);
284
0
285
0
        self.core_types.push(ty);
286
0
        ty_idx
287
0
    }
288
289
0
    fn get(&self, index: u32) -> &Rc<Type> {
290
0
        &self.types[index as usize]
291
0
    }
292
293
0
    fn get_core(&self, index: u32) -> &Rc<CoreType> {
294
0
        &self.core_types[index as usize]
295
0
    }
296
297
0
    fn get_func(&self, index: u32) -> &Rc<FuncType> {
298
0
        match &**self.get(index) {
299
0
            Type::Func(f) => f,
300
0
            _ => panic!("get_func on non-function type"),
301
        }
302
0
    }
303
304
0
    fn can_ref_type(&self) -> bool {
305
0
        // All component types and core module types may be referenced
306
0
        !self.types.is_empty() || !self.module_types.is_empty()
307
0
    }
308
}
309
310
impl<'a> Arbitrary<'a> for Component {
311
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
312
0
        Component::new(Config::default(), u)
313
0
    }
314
}
315
316
#[derive(Default)]
317
struct EntityCounts {
318
    globals: usize,
319
    tables: usize,
320
    memories: usize,
321
    tags: usize,
322
    funcs: usize,
323
}
324
325
impl Component {
326
    /// Construct a new `Component` using the given configuration.
327
0
    pub fn new(config: Config, u: &mut Unstructured) -> Result<Self> {
328
0
        let mut builder = ComponentBuilder::new(config);
329
0
        builder.build(u)
330
0
    }
331
332
0
    fn empty() -> Self {
333
0
        Component { sections: vec![] }
334
0
    }
335
}
336
337
#[must_use]
338
enum Step {
339
    Finished(Component),
340
    StillBuilding,
341
}
342
343
impl Step {
344
0
    fn unwrap_still_building(self) {
345
0
        match self {
346
0
            Step::Finished(_) => panic!(
347
0
                "`Step::unwrap_still_building` called on a `Step` that is not `StillBuilding`"
348
0
            ),
349
0
            Step::StillBuilding => {}
350
0
        }
351
0
    }
352
}
353
354
impl ComponentBuilder {
355
0
    fn new(config: Config) -> Self {
356
0
        ComponentBuilder {
357
0
            config,
358
0
            core_valtypes: vec![],
359
0
            types: vec![Default::default()],
360
0
            components: vec![ComponentContext::empty()],
361
0
            fill_minimums: false,
362
0
            total_components: 0,
363
0
            total_modules: 0,
364
0
            total_instances: 0,
365
0
            total_values: 0,
366
0
        }
367
0
    }
368
369
0
    fn build(&mut self, u: &mut Unstructured) -> Result<Component> {
370
0
        self.core_valtypes = crate::core::configured_valtypes(&self.config);
371
0
372
0
        let mut choices: Vec<fn(&mut ComponentBuilder, &mut Unstructured) -> Result<Step>> = vec![];
373
374
0
        loop {
375
0
            choices.clear();
376
0
            choices.push(Self::finish_component);
377
0
378
0
            // Only add any choice other than "finish what we've generated thus
379
0
            // far" when there is more arbitrary fuzzer data for us to consume.
380
0
            if !u.is_empty() {
381
0
                choices.push(Self::arbitrary_custom_section);
382
0
383
0
                // NB: we add each section as a choice even if we've already
384
0
                // generated our maximum number of entities in that section so that
385
0
                // we can exercise adding empty sections to the end of the module.
386
0
                choices.push(Self::arbitrary_core_type_section);
387
0
                choices.push(Self::arbitrary_type_section);
388
0
                choices.push(Self::arbitrary_import_section);
389
0
                choices.push(Self::arbitrary_canonical_section);
390
0
391
0
                if self.total_modules < self.config.max_modules {
392
0
                    choices.push(Self::arbitrary_core_module_section);
393
0
                }
394
395
0
                if self.components.len() < self.config.max_nesting_depth
396
0
                    && self.total_components < self.config.max_components
397
0
                {
398
0
                    choices.push(Self::arbitrary_component_section);
399
0
                }
400
401
                // FIXME(#1000)
402
                //
403
                // choices.push(Self::arbitrary_instance_section);
404
                // choices.push(Self::arbitrary_export_section);
405
                // choices.push(Self::arbitrary_start_section);
406
                // choices.push(Self::arbitrary_alias_section);
407
0
            }
408
409
0
            let f = u.choose(&choices)?;
410
0
            match f(self, u)? {
411
0
                Step::StillBuilding => {}
412
0
                Step::Finished(component) => {
413
0
                    if self.components.is_empty() {
414
                        // If we just finished the root component, then return it.
415
0
                        return Ok(component);
416
0
                    } else {
417
0
                        // Otherwise, add it as a nested component in the parent.
418
0
                        self.push_section(Section::Component(component));
419
0
                    }
420
                }
421
            }
422
        }
423
0
    }
424
425
0
    fn finish_component(&mut self, u: &mut Unstructured) -> Result<Step> {
426
0
        // Ensure we've generated all of our minimums.
427
0
        self.fill_minimums = true;
428
0
        {
429
0
            if self.current_type_scope().types.len() < self.config.min_types {
430
0
                self.arbitrary_type_section(u)?.unwrap_still_building();
431
0
            }
432
0
            if self.component().num_imports < self.config.min_imports {
433
0
                self.arbitrary_import_section(u)?.unwrap_still_building();
434
0
            }
435
0
            if self.component().funcs.len() < self.config.min_funcs {
436
0
                self.arbitrary_canonical_section(u)?.unwrap_still_building();
437
0
            }
438
        }
439
0
        self.fill_minimums = false;
440
0
441
0
        self.types
442
0
            .pop()
443
0
            .expect("should have a types scope for the component we are finishing");
444
0
        Ok(Step::Finished(self.components.pop().unwrap().component))
445
0
    }
446
447
0
    fn component(&self) -> &ComponentContext {
448
0
        self.components.last().unwrap()
449
0
    }
450
451
0
    fn component_mut(&mut self) -> &mut ComponentContext {
452
0
        self.components.last_mut().unwrap()
453
0
    }
454
455
0
    fn last_section(&self) -> Option<&Section> {
456
0
        self.component().component.sections.last()
457
0
    }
458
459
0
    fn last_section_mut(&mut self) -> Option<&mut Section> {
460
0
        self.component_mut().component.sections.last_mut()
461
0
    }
462
463
0
    fn push_section(&mut self, section: Section) {
464
0
        self.component_mut().component.sections.push(section);
465
0
    }
466
467
0
    fn ensure_section(
468
0
        &mut self,
469
0
        mut predicate: impl FnMut(&Section) -> bool,
470
0
        mut make_section: impl FnMut() -> Section,
471
0
    ) -> &mut Section {
472
0
        match self.last_section() {
473
0
            Some(sec) if predicate(sec) => {}
474
0
            _ => self.push_section(make_section()),
475
        }
476
0
        self.last_section_mut().unwrap()
477
0
    }
Unexecuted instantiation: _RINvMs4_NtCs4eJdYXiOSk9_10wasm_smith9componentNtB6_16ComponentBuilder14ensure_sectionNCNvB2_11push_import0NCB1n_s_0EB8_
Unexecuted instantiation: _RINvMs4_NtCs4eJdYXiOSk9_10wasm_smith9componentNtB6_16ComponentBuilder14ensure_sectionNCNvB2_14push_core_type0NCB1n_s_0EB8_
Unexecuted instantiation: _RINvMs4_NtCs4eJdYXiOSk9_10wasm_smith9componentNtB6_16ComponentBuilder14ensure_sectionNCNvB2_9push_type0NCB1n_s_0EB8_
478
479
0
    fn arbitrary_custom_section(&mut self, u: &mut Unstructured) -> Result<Step> {
480
0
        self.push_section(Section::Custom(u.arbitrary()?));
481
0
        Ok(Step::StillBuilding)
482
0
    }
483
484
0
    fn push_type(&mut self, ty: Rc<Type>) -> u32 {
485
0
        match self.ensure_section(
486
0
            |s| matches!(s, Section::Type(_)),
487
0
            || Section::Type(TypeSection { types: vec![] }),
488
0
        ) {
489
0
            Section::Type(TypeSection { types }) => {
490
0
                types.push(ty.clone());
491
0
                self.current_type_scope_mut().push(ty)
492
            }
493
0
            _ => unreachable!(),
494
        }
495
0
    }
496
497
0
    fn push_core_type(&mut self, ty: Rc<CoreType>) -> u32 {
498
0
        match self.ensure_section(
499
0
            |s| matches!(s, Section::CoreType(_)),
500
0
            || Section::CoreType(CoreTypeSection { types: vec![] }),
501
0
        ) {
502
0
            Section::CoreType(CoreTypeSection { types }) => {
503
0
                types.push(ty.clone());
504
0
                self.current_type_scope_mut().push_core(ty)
505
            }
506
0
            _ => unreachable!(),
507
        }
508
0
    }
509
510
0
    fn arbitrary_core_type_section(&mut self, u: &mut Unstructured) -> Result<Step> {
511
0
        self.push_section(Section::CoreType(CoreTypeSection { types: vec![] }));
512
513
0
        let min = if self.fill_minimums {
514
0
            self.config
515
0
                .min_types
516
0
                .saturating_sub(self.current_type_scope().types.len())
517
        } else {
518
0
            0
519
        };
520
521
0
        let max = self.config.max_types - self.current_type_scope().types.len();
522
0
523
0
        arbitrary_loop(u, min, max, |u| {
524
0
            let mut type_fuel = self.config.max_type_size;
525
0
            let ty = self.arbitrary_core_type(u, &mut type_fuel)?;
526
0
            self.push_core_type(ty);
527
0
            Ok(true)
528
0
        })?;
529
530
0
        Ok(Step::StillBuilding)
531
0
    }
532
533
0
    fn arbitrary_core_type(
534
0
        &self,
535
0
        u: &mut Unstructured,
536
0
        type_fuel: &mut u32,
537
0
    ) -> Result<Rc<CoreType>> {
538
0
        *type_fuel = type_fuel.saturating_sub(1);
539
0
        if *type_fuel == 0 {
540
0
            return Ok(Rc::new(CoreType::Module(Rc::new(ModuleType::default()))));
541
0
        }
542
543
0
        let ty = match u.int_in_range::<u8>(0..=1)? {
544
            0 => CoreType::Func(arbitrary_func_type(
545
0
                u,
546
0
                &self.config,
547
0
                &self.core_valtypes,
548
0
                if self.config.multi_value_enabled {
549
0
                    None
550
                } else {
551
0
                    Some(1)
552
                },
553
                0,
554
0
            )?),
555
0
            1 => CoreType::Module(self.arbitrary_module_type(u, type_fuel)?),
556
0
            _ => unreachable!(),
557
        };
558
0
        Ok(Rc::new(ty))
559
0
    }
560
561
0
    fn arbitrary_type_section(&mut self, u: &mut Unstructured) -> Result<Step> {
562
0
        self.push_section(Section::Type(TypeSection { types: vec![] }));
563
564
0
        let min = if self.fill_minimums {
565
0
            self.config
566
0
                .min_types
567
0
                .saturating_sub(self.current_type_scope().types.len())
568
        } else {
569
0
            0
570
        };
571
572
0
        let max = self.config.max_types - self.current_type_scope().types.len();
573
0
574
0
        arbitrary_loop(u, min, max, |u| {
575
0
            let mut type_fuel = self.config.max_type_size;
576
0
            let ty = self.arbitrary_type(u, &mut type_fuel)?;
577
0
            self.push_type(ty);
578
0
            Ok(true)
579
0
        })?;
580
581
0
        Ok(Step::StillBuilding)
582
0
    }
583
584
0
    fn arbitrary_type_ref<'a>(
585
0
        &self,
586
0
        u: &mut Unstructured<'a>,
587
0
        for_import: bool,
588
0
        for_type_def: bool,
589
0
    ) -> Result<Option<ComponentTypeRef>> {
590
0
        let mut choices: Vec<fn(&Self, &mut Unstructured) -> Result<ComponentTypeRef>> = Vec::new();
591
0
        let scope = self.current_type_scope();
592
0
593
0
        if !scope.module_types.is_empty()
594
0
            && (for_type_def || !for_import || self.total_modules < self.config.max_modules)
595
0
        {
596
0
            choices.push(|me, u| {
597
0
                Ok(ComponentTypeRef::Module(
598
0
                    *u.choose(&me.current_type_scope().module_types)?,
599
                ))
600
0
            });
601
0
        }
602
603
        // Types cannot be imported currently
604
0
        if !for_import
605
0
            && !scope.types.is_empty()
606
0
            && (for_type_def || scope.types.len() < self.config.max_types)
607
0
        {
608
0
            choices.push(|me, u| {
609
0
                Ok(ComponentTypeRef::Type(TypeBounds::Eq(u.int_in_range(
610
0
                    0..=u32::try_from(me.current_type_scope().types.len() - 1).unwrap(),
611
0
                )?)))
612
0
            });
613
0
        }
614
615
        // TODO: wasm-smith needs to ensure that every arbitrary value gets used exactly once.
616
        //       until that time, don't import values
617
        // if for_type_def || !for_import || self.total_values < self.config.max_values() {
618
        //     choices.push(|me, u| Ok(ComponentTypeRef::Value(me.arbitrary_component_val_type(u)?)));
619
        // }
620
621
0
        if !scope.func_types.is_empty()
622
0
            && (for_type_def || !for_import || self.component().num_funcs() < self.config.max_funcs)
623
0
        {
624
0
            choices.push(|me, u| {
625
0
                Ok(ComponentTypeRef::Func(
626
0
                    *u.choose(&me.current_type_scope().func_types)?,
627
                ))
628
0
            });
629
0
        }
630
631
0
        if !scope.component_types.is_empty()
632
0
            && (for_type_def || !for_import || self.total_components < self.config.max_components)
633
0
        {
634
0
            choices.push(|me, u| {
635
0
                Ok(ComponentTypeRef::Component(
636
0
                    *u.choose(&me.current_type_scope().component_types)?,
637
                ))
638
0
            });
639
0
        }
640
641
0
        if !scope.instance_types.is_empty()
642
0
            && (for_type_def || !for_import || self.total_instances < self.config.max_instances)
643
0
        {
644
0
            choices.push(|me, u| {
645
0
                Ok(ComponentTypeRef::Instance(
646
0
                    *u.choose(&me.current_type_scope().instance_types)?,
647
                ))
648
0
            });
649
0
        }
650
651
0
        if choices.is_empty() {
652
0
            return Ok(None);
653
0
        }
654
655
0
        let f = u.choose(&choices)?;
656
0
        f(self, u).map(Option::Some)
657
0
    }
658
659
0
    fn arbitrary_type(&mut self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<Rc<Type>> {
660
0
        *type_fuel = type_fuel.saturating_sub(1);
661
0
        if *type_fuel == 0 {
662
            return Ok(Rc::new(Type::Defined(
663
0
                self.arbitrary_defined_type(u, type_fuel)?,
664
            )));
665
0
        }
666
667
0
        let ty = match u.int_in_range::<u8>(0..=3)? {
668
0
            0 => Type::Defined(self.arbitrary_defined_type(u, type_fuel)?),
669
0
            1 => Type::Func(self.arbitrary_func_type(u, type_fuel)?),
670
0
            2 => Type::Component(self.arbitrary_component_type(u, type_fuel)?),
671
0
            3 => Type::Instance(self.arbitrary_instance_type(u, type_fuel)?),
672
0
            _ => unreachable!(),
673
        };
674
0
        Ok(Rc::new(ty))
675
0
    }
676
677
0
    fn arbitrary_module_type(
678
0
        &self,
679
0
        u: &mut Unstructured,
680
0
        type_fuel: &mut u32,
681
0
    ) -> Result<Rc<ModuleType>> {
682
0
        let mut defs = vec![];
683
0
        let mut has_memory = false;
684
0
        let mut has_canonical_abi_realloc = false;
685
0
        let mut has_canonical_abi_free = false;
686
0
        let mut types: Vec<Rc<crate::core::FuncType>> = vec![];
687
0
        let mut imports = HashMap::new();
688
0
        let mut exports = HashSet::new();
689
0
        let mut counts = EntityCounts::default();
690
0
691
0
        // Special case the canonical ABI functions since certain types can only
692
0
        // be passed across the component boundary if they exist and
693
0
        // randomly generating them is extremely unlikely.
694
0
695
0
        // `memory`
696
0
        if counts.memories < self.config.max_memories && u.ratio::<u8>(99, 100)? {
697
0
            defs.push(ModuleTypeDef::Export(
698
0
                "memory".into(),
699
0
                crate::core::EntityType::Memory(self.arbitrary_core_memory_type(u)?),
700
            ));
701
0
            exports.insert("memory".into());
702
0
            counts.memories += 1;
703
0
            has_memory = true;
704
0
        }
705
706
        // `canonical_abi_realloc`
707
0
        if counts.funcs < self.config.max_funcs
708
0
            && types.len() < self.config.max_types
709
0
            && u.ratio::<u8>(99, 100)?
710
0
        {
711
0
            let realloc_ty = Rc::new(crate::core::FuncType {
712
0
                params: vec![ValType::I32, ValType::I32, ValType::I32, ValType::I32],
713
0
                results: vec![ValType::I32],
714
0
            });
715
0
            let ty_idx = u32::try_from(types.len()).unwrap();
716
0
            types.push(realloc_ty.clone());
717
0
            defs.push(ModuleTypeDef::TypeDef(crate::core::CompositeType::Func(
718
0
                realloc_ty.clone(),
719
0
            )));
720
0
            defs.push(ModuleTypeDef::Export(
721
0
                "canonical_abi_realloc".into(),
722
0
                crate::core::EntityType::Func(ty_idx, realloc_ty),
723
0
            ));
724
0
            exports.insert("canonical_abi_realloc".into());
725
0
            counts.funcs += 1;
726
0
            has_canonical_abi_realloc = true;
727
0
        }
728
729
        // `canonical_abi_free`
730
0
        if counts.funcs < self.config.max_funcs
731
0
            && types.len() < self.config.max_types
732
0
            && u.ratio::<u8>(99, 100)?
733
0
        {
734
0
            let free_ty = Rc::new(crate::core::FuncType {
735
0
                params: vec![ValType::I32, ValType::I32, ValType::I32],
736
0
                results: vec![],
737
0
            });
738
0
            let ty_idx = u32::try_from(types.len()).unwrap();
739
0
            types.push(free_ty.clone());
740
0
            defs.push(ModuleTypeDef::TypeDef(crate::core::CompositeType::Func(
741
0
                free_ty.clone(),
742
0
            )));
743
0
            defs.push(ModuleTypeDef::Export(
744
0
                "canonical_abi_free".into(),
745
0
                crate::core::EntityType::Func(ty_idx, free_ty),
746
0
            ));
747
0
            exports.insert("canonical_abi_free".into());
748
0
            counts.funcs += 1;
749
0
            has_canonical_abi_free = true;
750
0
        }
751
752
0
        let mut entity_choices: Vec<
753
0
            fn(
754
0
                &ComponentBuilder,
755
0
                &mut Unstructured,
756
0
                &mut EntityCounts,
757
0
                &[Rc<crate::core::FuncType>],
758
0
            ) -> Result<crate::core::EntityType>,
759
0
        > = Vec::with_capacity(5);
760
0
761
0
        arbitrary_loop(u, 0, 100, |u| {
762
0
            *type_fuel = type_fuel.saturating_sub(1);
763
0
            if *type_fuel == 0 {
764
0
                return Ok(false);
765
0
            }
766
767
0
            let max_choice = if types.len() < self.config.max_types {
768
                // Check if the parent scope has core function types to alias
769
0
                if !types.is_empty()
770
0
                    || (!self.types.is_empty()
771
0
                        && !self.types.last().unwrap().core_func_types.is_empty())
772
                {
773
                    // Imports, exports, types, and aliases
774
0
                    3
775
                } else {
776
                    // Imports, exports, and types
777
0
                    2
778
                }
779
            } else {
780
                // Imports and exports
781
0
                1
782
            };
783
784
0
            match u.int_in_range::<u8>(0..=max_choice)? {
785
                // Import.
786
                0 => {
787
0
                    let module = crate::limited_string(100, u)?;
788
0
                    let existing_module_imports = imports.entry(module.clone()).or_default();
789
0
                    let field = crate::unique_string(100, existing_module_imports, u)?;
790
0
                    let entity_type = match self.arbitrary_core_entity_type(
791
0
                        u,
792
0
                        &types,
793
0
                        &mut entity_choices,
794
0
                        &mut counts,
795
0
                    )? {
796
0
                        None => return Ok(false),
797
0
                        Some(x) => x,
798
0
                    };
799
0
                    defs.push(ModuleTypeDef::Import(crate::core::Import {
800
0
                        module,
801
0
                        field,
802
0
                        entity_type,
803
0
                    }));
804
                }
805
806
                // Export.
807
                1 => {
808
0
                    let name = crate::unique_string(100, &mut exports, u)?;
809
0
                    let entity_ty = match self.arbitrary_core_entity_type(
810
0
                        u,
811
0
                        &types,
812
0
                        &mut entity_choices,
813
0
                        &mut counts,
814
0
                    )? {
815
0
                        None => return Ok(false),
816
0
                        Some(x) => x,
817
0
                    };
818
0
                    defs.push(ModuleTypeDef::Export(name, entity_ty));
819
                }
820
821
                // Type definition.
822
0
                2 => {
823
0
                    let ty = arbitrary_func_type(
824
0
                        u,
825
0
                        &self.config,
826
0
                        &self.core_valtypes,
827
0
                        if self.config.multi_value_enabled {
828
0
                            None
829
                        } else {
830
0
                            Some(1)
831
                        },
832
                        0,
833
0
                    )?;
834
0
                    types.push(ty.clone());
835
0
                    defs.push(ModuleTypeDef::TypeDef(crate::core::CompositeType::Func(ty)));
836
                }
837
838
                // Alias
839
0
                3 => {
840
0
                    let (count, index, kind) = self.arbitrary_outer_core_type_alias(u, &types)?;
841
0
                    let ty = match &kind {
842
0
                        CoreOuterAliasKind::Type(ty) => ty.clone(),
843
0
                    };
844
0
                    types.push(ty);
845
0
                    defs.push(ModuleTypeDef::OuterAlias {
846
0
                        count,
847
0
                        i: index,
848
0
                        kind,
849
0
                    });
850
                }
851
852
0
                _ => unreachable!(),
853
            }
854
855
0
            Ok(true)
856
0
        })?;
857
858
0
        Ok(Rc::new(ModuleType {
859
0
            defs,
860
0
            has_memory,
861
0
            has_canonical_abi_realloc,
862
0
            has_canonical_abi_free,
863
0
        }))
864
0
    }
865
866
0
    fn arbitrary_core_entity_type(
867
0
        &self,
868
0
        u: &mut Unstructured,
869
0
        types: &[Rc<crate::core::FuncType>],
870
0
        choices: &mut Vec<
871
0
            fn(
872
0
                &ComponentBuilder,
873
0
                &mut Unstructured,
874
0
                &mut EntityCounts,
875
0
                &[Rc<crate::core::FuncType>],
876
0
            ) -> Result<crate::core::EntityType>,
877
0
        >,
878
0
        counts: &mut EntityCounts,
879
0
    ) -> Result<Option<crate::core::EntityType>> {
880
0
        choices.clear();
881
0
882
0
        if counts.globals < self.config.max_globals {
883
0
            choices.push(|c, u, counts, _types| {
884
0
                counts.globals += 1;
885
0
                Ok(crate::core::EntityType::Global(
886
0
                    c.arbitrary_core_global_type(u)?,
887
                ))
888
0
            });
889
0
        }
890
891
0
        if counts.tables < self.config.max_tables {
892
0
            choices.push(|c, u, counts, _types| {
893
0
                counts.tables += 1;
894
0
                Ok(crate::core::EntityType::Table(
895
0
                    c.arbitrary_core_table_type(u)?,
896
                ))
897
0
            });
898
0
        }
899
900
0
        if counts.memories < self.config.max_memories {
901
0
            choices.push(|c, u, counts, _types| {
902
0
                counts.memories += 1;
903
0
                Ok(crate::core::EntityType::Memory(
904
0
                    c.arbitrary_core_memory_type(u)?,
905
                ))
906
0
            });
907
0
        }
908
909
0
        if types.iter().any(|ty| ty.results.is_empty())
910
0
            && self.config.exceptions_enabled
911
0
            && counts.tags < self.config.max_tags
912
0
        {
913
0
            choices.push(|c, u, counts, types| {
914
0
                counts.tags += 1;
915
0
                let tag_func_types = types
916
0
                    .iter()
917
0
                    .enumerate()
918
0
                    .filter(|(_, ty)| ty.results.is_empty())
919
0
                    .map(|(i, _)| u32::try_from(i).unwrap())
920
0
                    .collect::<Vec<_>>();
921
0
                Ok(crate::core::EntityType::Tag(
922
0
                    crate::core::arbitrary_tag_type(u, &tag_func_types, |idx| {
923
0
                        types[usize::try_from(idx).unwrap()].clone()
924
0
                    })?,
925
                ))
926
0
            });
927
0
        }
928
929
0
        if !types.is_empty() && counts.funcs < self.config.max_funcs {
930
0
            choices.push(|c, u, counts, types| {
931
0
                counts.funcs += 1;
932
0
                let ty_idx = u.int_in_range(0..=u32::try_from(types.len() - 1).unwrap())?;
933
0
                let ty = types[ty_idx as usize].clone();
934
0
                Ok(crate::core::EntityType::Func(ty_idx, ty))
935
0
            });
936
0
        }
937
938
0
        if choices.is_empty() {
939
0
            return Ok(None);
940
0
        }
941
942
0
        let f = u.choose(choices)?;
943
0
        let ty = f(self, u, counts, types)?;
944
0
        Ok(Some(ty))
945
0
    }
946
947
0
    fn arbitrary_core_valtype(&self, u: &mut Unstructured) -> Result<ValType> {
948
0
        Ok(*u.choose(&self.core_valtypes)?)
949
0
    }
950
951
0
    fn arbitrary_core_global_type(&self, u: &mut Unstructured) -> Result<crate::core::GlobalType> {
952
0
        Ok(crate::core::GlobalType {
953
0
            val_type: self.arbitrary_core_valtype(u)?,
954
0
            mutable: u.arbitrary()?,
955
            shared: false,
956
        })
957
0
    }
958
959
0
    fn arbitrary_core_table_type(&self, u: &mut Unstructured) -> Result<crate::core::TableType> {
960
0
        crate::core::arbitrary_table_type(u, &self.config, None)
961
0
    }
962
963
0
    fn arbitrary_core_memory_type(&self, u: &mut Unstructured) -> Result<crate::core::MemoryType> {
964
0
        crate::core::arbitrary_memtype(u, &self.config)
965
0
    }
966
967
0
    fn with_types_scope<T>(&mut self, f: impl FnOnce(&mut Self) -> Result<T>) -> Result<T> {
968
0
        self.types.push(Default::default());
969
0
        let result = f(self);
970
0
        self.types.pop();
971
0
        result
972
0
    }
Unexecuted instantiation: _RINvMs4_NtCs4eJdYXiOSk9_10wasm_smith9componentNtB6_16ComponentBuilder16with_types_scopeuNCNvB2_23arbitrary_instance_type0EB8_
Unexecuted instantiation: _RINvMs4_NtCs4eJdYXiOSk9_10wasm_smith9componentNtB6_16ComponentBuilder16with_types_scopeuNCNvB2_24arbitrary_component_type0EB8_
973
974
0
    fn current_type_scope(&self) -> &TypesScope {
975
0
        self.types.last().unwrap()
976
0
    }
977
978
0
    fn current_type_scope_mut(&mut self) -> &mut TypesScope {
979
0
        self.types.last_mut().unwrap()
980
0
    }
981
982
0
    fn outer_types_scope(&self, count: u32) -> &TypesScope {
983
0
        &self.types[self.types.len() - 1 - usize::try_from(count).unwrap()]
984
0
    }
985
986
0
    fn outer_type(&self, count: u32, i: u32) -> &Rc<Type> {
987
0
        &self.outer_types_scope(count).types[usize::try_from(i).unwrap()]
988
0
    }
989
990
0
    fn arbitrary_component_type(
991
0
        &mut self,
992
0
        u: &mut Unstructured,
993
0
        type_fuel: &mut u32,
994
0
    ) -> Result<Rc<ComponentType>> {
995
0
        let mut defs = vec![];
996
0
        let mut imports = HashSet::new();
997
0
        let mut import_urls = HashSet::new();
998
0
        let mut exports = HashSet::new();
999
0
        let mut export_urls = HashSet::new();
1000
0
1001
0
        self.with_types_scope(|me| {
1002
0
            arbitrary_loop(u, 0, 100, |u| {
1003
0
                *type_fuel = type_fuel.saturating_sub(1);
1004
0
                if *type_fuel == 0 {
1005
0
                    return Ok(false);
1006
0
                }
1007
0
1008
0
                if me.current_type_scope().can_ref_type() && u.int_in_range::<u8>(0..=3)? == 0 {
1009
0
                    if let Some(ty) = me.arbitrary_type_ref(u, true, true)? {
1010
                        // Imports.
1011
0
                        let name = crate::unique_kebab_string(100, &mut imports, u)?;
1012
0
                        let url = if u.arbitrary()? {
1013
0
                            Some(crate::unique_url(100, &mut import_urls, u)?)
1014
                        } else {
1015
0
                            None
1016
                        };
1017
0
                        defs.push(ComponentTypeDef::Import(Import { name, url, ty }));
1018
0
                        return Ok(true);
1019
0
                    }
1020
1021
                    // Can't reference an arbitrary type, fallback to another definition.
1022
0
                }
1023
1024
                // Type definitions, exports, and aliases.
1025
0
                let def =
1026
0
                    me.arbitrary_instance_type_def(u, &mut exports, &mut export_urls, type_fuel)?;
1027
0
                defs.push(def.into());
1028
0
                Ok(true)
1029
0
            })
1030
0
        })?;
1031
1032
0
        Ok(Rc::new(ComponentType { defs }))
1033
0
    }
1034
1035
0
    fn arbitrary_instance_type(
1036
0
        &mut self,
1037
0
        u: &mut Unstructured,
1038
0
        type_fuel: &mut u32,
1039
0
    ) -> Result<Rc<InstanceType>> {
1040
0
        let mut defs = vec![];
1041
0
        let mut exports = HashSet::new();
1042
0
        let mut export_urls = HashSet::new();
1043
0
1044
0
        self.with_types_scope(|me| {
1045
0
            arbitrary_loop(u, 0, 100, |u| {
1046
0
                *type_fuel = type_fuel.saturating_sub(1);
1047
0
                if *type_fuel == 0 {
1048
0
                    return Ok(false);
1049
0
                }
1050
0
1051
0
                defs.push(me.arbitrary_instance_type_def(
1052
0
                    u,
1053
0
                    &mut exports,
1054
0
                    &mut export_urls,
1055
0
                    type_fuel,
1056
0
                )?);
1057
0
                Ok(true)
1058
0
            })
1059
0
        })?;
1060
1061
0
        Ok(Rc::new(InstanceType { defs }))
1062
0
    }
1063
1064
0
    fn arbitrary_instance_type_def(
1065
0
        &mut self,
1066
0
        u: &mut Unstructured,
1067
0
        exports: &mut HashSet<String>,
1068
0
        export_urls: &mut HashSet<String>,
1069
0
        type_fuel: &mut u32,
1070
0
    ) -> Result<InstanceTypeDecl> {
1071
0
        let mut choices: Vec<
1072
0
            fn(
1073
0
                &mut ComponentBuilder,
1074
0
                &mut HashSet<String>,
1075
0
                &mut HashSet<String>,
1076
0
                &mut Unstructured,
1077
0
                &mut u32,
1078
0
            ) -> Result<InstanceTypeDecl>,
1079
0
        > = Vec::with_capacity(3);
1080
0
1081
0
        // Export.
1082
0
        if self.current_type_scope().can_ref_type() {
1083
0
            choices.push(|me, exports, export_urls, u, _type_fuel| {
1084
0
                let ty = me.arbitrary_type_ref(u, false, true)?.unwrap();
1085
0
                if let ComponentTypeRef::Type(TypeBounds::Eq(idx)) = ty {
1086
0
                    let ty = me.current_type_scope().get(idx).clone();
1087
0
                    me.current_type_scope_mut().push(ty);
1088
0
                }
1089
                Ok(InstanceTypeDecl::Export {
1090
0
                    name: crate::unique_kebab_string(100, exports, u)?,
1091
0
                    url: if u.arbitrary()? {
1092
0
                        Some(crate::unique_url(100, export_urls, u)?)
1093
                    } else {
1094
0
                        None
1095
                    },
1096
0
                    ty,
1097
                })
1098
0
            });
1099
0
        }
1100
1101
        // Outer type alias.
1102
0
        if self
1103
0
            .types
1104
0
            .iter()
1105
0
            .any(|scope| !scope.types.is_empty() || !scope.core_types.is_empty())
1106
0
        {
1107
0
            choices.push(|me, _exports, _export_urls, u, _type_fuel| {
1108
0
                let alias = me.arbitrary_outer_type_alias(u)?;
1109
0
                match &alias {
1110
                    Alias::Outer {
1111
0
                        kind: OuterAliasKind::Type(ty),
1112
0
                        ..
1113
0
                    } => me.current_type_scope_mut().push(ty.clone()),
1114
                    Alias::Outer {
1115
0
                        kind: OuterAliasKind::CoreType(ty),
1116
0
                        ..
1117
0
                    } => me.current_type_scope_mut().push_core(ty.clone()),
1118
0
                    _ => unreachable!(),
1119
                };
1120
0
                Ok(InstanceTypeDecl::Alias(alias))
1121
0
            });
1122
0
        }
1123
1124
        // Core type definition.
1125
0
        choices.push(|me, _exports, _export_urls, u, type_fuel| {
1126
0
            let ty = me.arbitrary_core_type(u, type_fuel)?;
1127
0
            me.current_type_scope_mut().push_core(ty.clone());
1128
0
            Ok(InstanceTypeDecl::CoreType(ty))
1129
0
        });
1130
0
1131
0
        // Type definition.
1132
0
        if self.types.len() < self.config.max_nesting_depth {
1133
0
            choices.push(|me, _exports, _export_urls, u, type_fuel| {
1134
0
                let ty = me.arbitrary_type(u, type_fuel)?;
1135
0
                me.current_type_scope_mut().push(ty.clone());
1136
0
                Ok(InstanceTypeDecl::Type(ty))
1137
0
            });
1138
0
        }
1139
1140
0
        let f = u.choose(&choices)?;
1141
0
        f(self, exports, export_urls, u, type_fuel)
1142
0
    }
1143
1144
0
    fn arbitrary_outer_core_type_alias(
1145
0
        &self,
1146
0
        u: &mut Unstructured,
1147
0
        local_types: &[Rc<crate::core::FuncType>],
1148
0
    ) -> Result<(u32, u32, CoreOuterAliasKind)> {
1149
0
        let enclosing_type_len = if !self.types.is_empty() {
1150
0
            self.types.last().unwrap().core_func_types.len()
1151
        } else {
1152
0
            0
1153
        };
1154
1155
0
        assert!(!local_types.is_empty() || enclosing_type_len > 0);
1156
1157
0
        let max = enclosing_type_len + local_types.len() - 1;
1158
0
        let i = u.int_in_range(0..=max)?;
1159
0
        let (count, index, ty) = if i < enclosing_type_len {
1160
0
            let enclosing = self.types.last().unwrap();
1161
0
            let index = enclosing.core_func_types[i];
1162
0
            (
1163
0
                1,
1164
0
                index,
1165
0
                match enclosing.get_core(index).as_ref() {
1166
0
                    CoreType::Func(ty) => ty.clone(),
1167
0
                    CoreType::Module(_) => unreachable!(),
1168
                },
1169
            )
1170
0
        } else if i - enclosing_type_len < local_types.len() {
1171
0
            let i = i - enclosing_type_len;
1172
0
            (0, u32::try_from(i).unwrap(), local_types[i].clone())
1173
        } else {
1174
0
            unreachable!()
1175
        };
1176
1177
0
        Ok((count, index, CoreOuterAliasKind::Type(ty)))
1178
0
    }
1179
1180
0
    fn arbitrary_outer_type_alias(&self, u: &mut Unstructured) -> Result<Alias> {
1181
0
        let non_empty_types_scopes: Vec<_> = self
1182
0
            .types
1183
0
            .iter()
1184
0
            .rev()
1185
0
            .enumerate()
1186
0
            .filter(|(_, scope)| !scope.types.is_empty() || !scope.core_types.is_empty())
1187
0
            .collect();
1188
0
        assert!(
1189
0
            !non_empty_types_scopes.is_empty(),
1190
0
            "precondition: there are non-empty types scopes"
1191
        );
1192
1193
0
        let (count, scope) = u.choose(&non_empty_types_scopes)?;
1194
0
        let count = u32::try_from(*count).unwrap();
1195
0
        assert!(!scope.types.is_empty() || !scope.core_types.is_empty());
1196
1197
0
        let max_type_in_scope = scope.types.len() + scope.core_types.len() - 1;
1198
0
        let i = u.int_in_range(0..=max_type_in_scope)?;
1199
1200
0
        let (i, kind) = if i < scope.types.len() {
1201
0
            let i = u32::try_from(i).unwrap();
1202
0
            (i, OuterAliasKind::Type(Rc::clone(scope.get(i))))
1203
0
        } else if i - scope.types.len() < scope.core_types.len() {
1204
0
            let i = u32::try_from(i - scope.types.len()).unwrap();
1205
0
            (i, OuterAliasKind::CoreType(Rc::clone(scope.get_core(i))))
1206
        } else {
1207
0
            unreachable!()
1208
        };
1209
1210
0
        Ok(Alias::Outer { count, i, kind })
1211
0
    }
1212
1213
0
    fn arbitrary_func_type(
1214
0
        &self,
1215
0
        u: &mut Unstructured,
1216
0
        type_fuel: &mut u32,
1217
0
    ) -> Result<Rc<FuncType>> {
1218
0
        let mut params = Vec::new();
1219
0
        let mut results = Vec::new();
1220
0
        let mut names = HashSet::new();
1221
0
1222
0
        // Note: parameters are currently limited to a maximum of 16
1223
0
        // because any additional parameters will require indirect access
1224
0
        // via a pointer argument; when this occurs, validation of any
1225
0
        // lowered function will fail because it will be missing a
1226
0
        // memory option (not yet implemented).
1227
0
        //
1228
0
        // When options are correctly specified on canonical functions,
1229
0
        // we should increase this maximum to test indirect parameter
1230
0
        // passing.
1231
0
        arbitrary_loop(u, 0, 16, |u| {
1232
0
            *type_fuel = type_fuel.saturating_sub(1);
1233
0
            if *type_fuel == 0 {
1234
0
                return Ok(false);
1235
0
            }
1236
1237
0
            let name = crate::unique_kebab_string(100, &mut names, u)?;
1238
0
            let ty = self.arbitrary_component_val_type(u)?;
1239
1240
0
            params.push((name, ty));
1241
0
1242
0
            Ok(true)
1243
0
        })?;
1244
1245
0
        names.clear();
1246
0
1247
0
        // Likewise, the limit for results is 1 before the memory option is
1248
0
        // required. When the memory option is implemented, this restriction
1249
0
        // should be relaxed.
1250
0
        arbitrary_loop(u, 0, 1, |u| {
1251
0
            *type_fuel = type_fuel.saturating_sub(1);
1252
0
            if *type_fuel == 0 {
1253
0
                return Ok(false);
1254
0
            }
1255
1256
            // If the result list is empty (i.e. first push), then arbitrarily give
1257
            // the result a name. Otherwise, all of the subsequent items must be named.
1258
0
            let name = if results.is_empty() {
1259
                // Most of the time we should have a single, unnamed result.
1260
0
                u.ratio::<u8>(10, 100)?
1261
0
                    .then(|| crate::unique_kebab_string(100, &mut names, u))
1262
0
                    .transpose()?
1263
            } else {
1264
0
                Some(crate::unique_kebab_string(100, &mut names, u)?)
1265
            };
1266
1267
0
            let ty = self.arbitrary_component_val_type(u)?;
1268
1269
0
            results.push((name, ty));
1270
0
1271
0
            // There can be only one unnamed result.
1272
0
            if results.len() == 1 && results[0].0.is_none() {
1273
0
                return Ok(false);
1274
0
            }
1275
0
1276
0
            Ok(true)
1277
0
        })?;
1278
1279
0
        Ok(Rc::new(FuncType { params, results }))
1280
0
    }
1281
1282
0
    fn arbitrary_component_val_type(&self, u: &mut Unstructured) -> Result<ComponentValType> {
1283
0
        let max_choices = if self.current_type_scope().defined_types.is_empty() {
1284
0
            0
1285
        } else {
1286
0
            1
1287
        };
1288
0
        match u.int_in_range(0..=max_choices)? {
1289
            0 => Ok(ComponentValType::Primitive(
1290
0
                self.arbitrary_primitive_val_type(u)?,
1291
            )),
1292
            1 => {
1293
0
                let index = *u.choose(&self.current_type_scope().defined_types)?;
1294
0
                let ty = Rc::clone(self.current_type_scope().get(index));
1295
0
                Ok(ComponentValType::Type(index))
1296
            }
1297
0
            _ => unreachable!(),
1298
        }
1299
0
    }
1300
1301
0
    fn arbitrary_primitive_val_type(&self, u: &mut Unstructured) -> Result<PrimitiveValType> {
1302
0
        match u.int_in_range(0..=12)? {
1303
0
            0 => Ok(PrimitiveValType::Bool),
1304
0
            1 => Ok(PrimitiveValType::S8),
1305
0
            2 => Ok(PrimitiveValType::U8),
1306
0
            3 => Ok(PrimitiveValType::S16),
1307
0
            4 => Ok(PrimitiveValType::U16),
1308
0
            5 => Ok(PrimitiveValType::S32),
1309
0
            6 => Ok(PrimitiveValType::U32),
1310
0
            7 => Ok(PrimitiveValType::S64),
1311
0
            8 => Ok(PrimitiveValType::U64),
1312
0
            9 => Ok(PrimitiveValType::F32),
1313
0
            10 => Ok(PrimitiveValType::F64),
1314
0
            11 => Ok(PrimitiveValType::Char),
1315
0
            12 => Ok(PrimitiveValType::String),
1316
0
            _ => unreachable!(),
1317
        }
1318
0
    }
1319
1320
0
    fn arbitrary_record_type(
1321
0
        &self,
1322
0
        u: &mut Unstructured,
1323
0
        type_fuel: &mut u32,
1324
0
    ) -> Result<RecordType> {
1325
0
        let mut fields = vec![];
1326
0
        let mut field_names = HashSet::new();
1327
0
        arbitrary_loop(u, 0, 100, |u| {
1328
0
            *type_fuel = type_fuel.saturating_sub(1);
1329
0
            if *type_fuel == 0 {
1330
0
                return Ok(false);
1331
0
            }
1332
1333
0
            let name = crate::unique_kebab_string(100, &mut field_names, u)?;
1334
0
            let ty = self.arbitrary_component_val_type(u)?;
1335
1336
0
            fields.push((name, ty));
1337
0
            Ok(true)
1338
0
        })?;
1339
0
        Ok(RecordType { fields })
1340
0
    }
1341
1342
0
    fn arbitrary_variant_type(
1343
0
        &self,
1344
0
        u: &mut Unstructured,
1345
0
        type_fuel: &mut u32,
1346
0
    ) -> Result<VariantType> {
1347
0
        let mut cases = vec![];
1348
0
        let mut case_names = HashSet::new();
1349
0
        arbitrary_loop(u, 1, 100, |u| {
1350
0
            *type_fuel = type_fuel.saturating_sub(1);
1351
0
            if *type_fuel == 0 {
1352
0
                return Ok(false);
1353
0
            }
1354
1355
0
            let name = crate::unique_kebab_string(100, &mut case_names, u)?;
1356
1357
0
            let ty = u
1358
0
                .arbitrary::<bool>()?
1359
0
                .then(|| self.arbitrary_component_val_type(u))
1360
0
                .transpose()?;
1361
1362
0
            let refines = if !cases.is_empty() && u.arbitrary()? {
1363
0
                let max_cases = u32::try_from(cases.len() - 1).unwrap();
1364
0
                Some(u.int_in_range(0..=max_cases)?)
1365
            } else {
1366
0
                None
1367
            };
1368
1369
0
            cases.push((name, ty, refines));
1370
0
            Ok(true)
1371
0
        })?;
1372
1373
0
        Ok(VariantType { cases })
1374
0
    }
1375
1376
0
    fn arbitrary_list_type(&self, u: &mut Unstructured) -> Result<ListType> {
1377
0
        Ok(ListType {
1378
0
            elem_ty: self.arbitrary_component_val_type(u)?,
1379
        })
1380
0
    }
1381
1382
0
    fn arbitrary_tuple_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<TupleType> {
1383
0
        let mut fields = vec![];
1384
0
        arbitrary_loop(u, 0, 100, |u| {
1385
0
            *type_fuel = type_fuel.saturating_sub(1);
1386
0
            if *type_fuel == 0 {
1387
0
                return Ok(false);
1388
0
            }
1389
0
1390
0
            fields.push(self.arbitrary_component_val_type(u)?);
1391
0
            Ok(true)
1392
0
        })?;
1393
0
        Ok(TupleType { fields })
1394
0
    }
1395
1396
0
    fn arbitrary_flags_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<FlagsType> {
1397
0
        let mut fields = vec![];
1398
0
        let mut field_names = HashSet::new();
1399
0
        arbitrary_loop(u, 0, 100, |u| {
1400
0
            *type_fuel = type_fuel.saturating_sub(1);
1401
0
            if *type_fuel == 0 {
1402
0
                return Ok(false);
1403
0
            }
1404
0
1405
0
            fields.push(crate::unique_kebab_string(100, &mut field_names, u)?);
1406
0
            Ok(true)
1407
0
        })?;
1408
0
        Ok(FlagsType { fields })
1409
0
    }
1410
1411
0
    fn arbitrary_enum_type(&self, u: &mut Unstructured, type_fuel: &mut u32) -> Result<EnumType> {
1412
0
        let mut variants = vec![];
1413
0
        let mut variant_names = HashSet::new();
1414
0
        arbitrary_loop(u, 1, 100, |u| {
1415
0
            *type_fuel = type_fuel.saturating_sub(1);
1416
0
            if *type_fuel == 0 {
1417
0
                return Ok(false);
1418
0
            }
1419
0
1420
0
            variants.push(crate::unique_kebab_string(100, &mut variant_names, u)?);
1421
0
            Ok(true)
1422
0
        })?;
1423
0
        Ok(EnumType { variants })
1424
0
    }
1425
1426
0
    fn arbitrary_option_type(&self, u: &mut Unstructured) -> Result<OptionType> {
1427
0
        Ok(OptionType {
1428
0
            inner_ty: self.arbitrary_component_val_type(u)?,
1429
        })
1430
0
    }
1431
1432
0
    fn arbitrary_result_type(&self, u: &mut Unstructured) -> Result<ResultType> {
1433
0
        Ok(ResultType {
1434
0
            ok_ty: u
1435
0
                .arbitrary::<bool>()?
1436
0
                .then(|| self.arbitrary_component_val_type(u))
1437
0
                .transpose()?,
1438
0
            err_ty: u
1439
0
                .arbitrary::<bool>()?
1440
0
                .then(|| self.arbitrary_component_val_type(u))
1441
0
                .transpose()?,
1442
        })
1443
0
    }
1444
1445
0
    fn arbitrary_defined_type(
1446
0
        &self,
1447
0
        u: &mut Unstructured,
1448
0
        type_fuel: &mut u32,
1449
0
    ) -> Result<DefinedType> {
1450
0
        match u.int_in_range(0..=8)? {
1451
            0 => Ok(DefinedType::Primitive(
1452
0
                self.arbitrary_primitive_val_type(u)?,
1453
            )),
1454
            1 => Ok(DefinedType::Record(
1455
0
                self.arbitrary_record_type(u, type_fuel)?,
1456
            )),
1457
            2 => Ok(DefinedType::Variant(
1458
0
                self.arbitrary_variant_type(u, type_fuel)?,
1459
            )),
1460
0
            3 => Ok(DefinedType::List(self.arbitrary_list_type(u)?)),
1461
0
            4 => Ok(DefinedType::Tuple(self.arbitrary_tuple_type(u, type_fuel)?)),
1462
0
            5 => Ok(DefinedType::Flags(self.arbitrary_flags_type(u, type_fuel)?)),
1463
0
            6 => Ok(DefinedType::Enum(self.arbitrary_enum_type(u, type_fuel)?)),
1464
0
            7 => Ok(DefinedType::Option(self.arbitrary_option_type(u)?)),
1465
0
            8 => Ok(DefinedType::Result(self.arbitrary_result_type(u)?)),
1466
0
            _ => unreachable!(),
1467
        }
1468
0
    }
1469
1470
0
    fn push_import(&mut self, name: String, url: Option<String>, ty: ComponentTypeRef) {
1471
0
        let nth = match self.ensure_section(
1472
0
            |sec| matches!(sec, Section::Import(_)),
1473
0
            || Section::Import(ImportSection { imports: vec![] }),
1474
0
        ) {
1475
0
            Section::Import(sec) => {
1476
0
                sec.imports.push(Import { name, url, ty });
1477
0
                sec.imports.len() - 1
1478
            }
1479
0
            _ => unreachable!(),
1480
        };
1481
0
        let section_index = self.component().component.sections.len() - 1;
1482
1483
0
        match ty {
1484
0
            ComponentTypeRef::Module(_) => {
1485
0
                self.total_modules += 1;
1486
0
                self.component_mut().modules.push((section_index, nth));
1487
0
            }
1488
0
            ComponentTypeRef::Func(ty_index) => {
1489
0
                let func_ty = match self.current_type_scope().get(ty_index).as_ref() {
1490
0
                    Type::Func(ty) => ty.clone(),
1491
0
                    _ => unreachable!(),
1492
                };
1493
1494
0
                if func_ty.is_scalar() {
1495
0
                    let func_index = u32::try_from(self.component().component_funcs.len()).unwrap();
1496
0
                    self.component_mut().scalar_component_funcs.push(func_index);
1497
0
                }
1498
1499
0
                let func_index = u32::try_from(self.component().funcs.len()).unwrap();
1500
0
                self.component_mut()
1501
0
                    .funcs
1502
0
                    .push(ComponentOrCoreFuncType::Component(func_ty));
1503
0
1504
0
                self.component_mut().component_funcs.push(func_index);
1505
            }
1506
0
            ComponentTypeRef::Value(ty) => {
1507
0
                self.total_values += 1;
1508
0
                self.component_mut().values.push(ty);
1509
0
            }
1510
0
            ComponentTypeRef::Type(TypeBounds::Eq(ty_index)) => {
1511
0
                let ty = self.current_type_scope().get(ty_index).clone();
1512
0
                self.current_type_scope_mut().push(ty);
1513
0
            }
1514
            ComponentTypeRef::Type(TypeBounds::SubResource) => {
1515
0
                unimplemented!()
1516
            }
1517
0
            ComponentTypeRef::Instance(ty_index) => {
1518
0
                let instance_ty = match self.current_type_scope().get(ty_index).as_ref() {
1519
0
                    Type::Instance(ty) => ty.clone(),
1520
0
                    _ => unreachable!(),
1521
                };
1522
1523
0
                self.total_instances += 1;
1524
0
                self.component_mut()
1525
0
                    .instances
1526
0
                    .push(ComponentOrCoreInstanceType::Component(instance_ty));
1527
            }
1528
0
            ComponentTypeRef::Component(_) => {
1529
0
                self.total_components += 1;
1530
0
                self.component_mut().components.push((section_index, nth));
1531
0
            }
1532
        }
1533
0
    }
1534
1535
0
    fn core_function_type(&self, core_func_index: u32) -> &Rc<crate::core::FuncType> {
1536
0
        self.component().funcs[self.component().core_funcs[core_func_index as usize] as usize]
1537
0
            .as_core()
1538
0
    }
1539
1540
0
    fn component_function_type(&self, func_index: u32) -> &Rc<FuncType> {
1541
0
        self.component().funcs[self.component().component_funcs[func_index as usize] as usize]
1542
0
            .as_component()
1543
0
    }
1544
1545
0
    fn push_func(&mut self, func: Func) {
1546
0
        let nth = match self.component_mut().component.sections.last_mut() {
1547
0
            Some(Section::Canonical(CanonicalSection { funcs })) => funcs.len(),
1548
            _ => {
1549
0
                self.push_section(Section::Canonical(CanonicalSection { funcs: vec![] }));
1550
0
                0
1551
            }
1552
        };
1553
0
        let section_index = self.component().component.sections.len() - 1;
1554
0
1555
0
        let func_index = u32::try_from(self.component().funcs.len()).unwrap();
1556
1557
0
        let ty = match &func {
1558
0
            Func::CanonLift { func_ty, .. } => {
1559
0
                let ty = Rc::clone(self.current_type_scope().get_func(*func_ty));
1560
0
                if ty.is_scalar() {
1561
0
                    let func_index = u32::try_from(self.component().component_funcs.len()).unwrap();
1562
0
                    self.component_mut().scalar_component_funcs.push(func_index);
1563
0
                }
1564
0
                self.component_mut().component_funcs.push(func_index);
1565
0
                ComponentOrCoreFuncType::Component(ty)
1566
            }
1567
            Func::CanonLower {
1568
0
                func_index: comp_func_index,
1569
0
                ..
1570
0
            } => {
1571
0
                let comp_func_ty = self.component_function_type(*comp_func_index);
1572
0
                let core_func_ty = canonical_abi_for(comp_func_ty);
1573
0
                self.component_mut().core_funcs.push(func_index);
1574
0
                ComponentOrCoreFuncType::Core(core_func_ty)
1575
            }
1576
        };
1577
1578
0
        self.component_mut().funcs.push(ty);
1579
0
1580
0
        match self.component_mut().component.sections.last_mut() {
1581
0
            Some(Section::Canonical(CanonicalSection { funcs })) => funcs.push(func),
1582
0
            _ => unreachable!(),
1583
        }
1584
0
    }
1585
1586
0
    fn arbitrary_import_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1587
0
        self.push_section(Section::Import(ImportSection { imports: vec![] }));
1588
1589
0
        let min = if self.fill_minimums {
1590
0
            self.config
1591
0
                .min_imports
1592
0
                .saturating_sub(self.component().num_imports)
1593
        } else {
1594
            // Allow generating empty sections. We can always fill in the required
1595
            // minimum later.
1596
0
            0
1597
        };
1598
0
        let max = self.config.max_imports - self.component().num_imports;
1599
0
1600
0
        crate::arbitrary_loop(u, min, max, |u| {
1601
0
            match self.arbitrary_type_ref(u, true, false)? {
1602
0
                Some(ty) => {
1603
0
                    let name =
1604
0
                        crate::unique_kebab_string(100, &mut self.component_mut().import_names, u)?;
1605
0
                    let url = if u.arbitrary()? {
1606
0
                        Some(crate::unique_url(
1607
0
                            100,
1608
0
                            &mut self.component_mut().import_urls,
1609
0
                            u,
1610
0
                        )?)
1611
                    } else {
1612
0
                        None
1613
                    };
1614
0
                    self.push_import(name, url, ty);
1615
0
                    Ok(true)
1616
                }
1617
0
                None => Ok(false),
1618
            }
1619
0
        })?;
1620
1621
0
        Ok(Step::StillBuilding)
1622
0
    }
1623
1624
0
    fn arbitrary_canonical_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1625
0
        self.push_section(Section::Canonical(CanonicalSection { funcs: vec![] }));
1626
1627
0
        let min = if self.fill_minimums {
1628
0
            self.config
1629
0
                .min_funcs
1630
0
                .saturating_sub(self.component().funcs.len())
1631
        } else {
1632
            // Allow generating empty sections. We can always fill in the
1633
            // required minimum later.
1634
0
            0
1635
        };
1636
0
        let max = self.config.max_funcs - self.component().funcs.len();
1637
0
1638
0
        let mut choices: Vec<fn(&mut Unstructured, &mut ComponentBuilder) -> Result<Option<Func>>> =
1639
0
            Vec::with_capacity(2);
1640
0
1641
0
        crate::arbitrary_loop(u, min, max, |u| {
1642
0
            choices.clear();
1643
0
1644
0
            // NB: We only lift/lower scalar component functions.
1645
0
            //
1646
0
            // If we generated lifting and lowering of compound value types,
1647
0
            // the probability of generating a corresponding Wasm module that
1648
0
            // generates valid instances of the compound value types would
1649
0
            // be vanishingly tiny (e.g. for `list<string>` we would have to
1650
0
            // generate a core Wasm module that correctly produces a pointer and
1651
0
            // length for a memory region that itself is a series of pointers
1652
0
            // and lengths of valid strings, as well as `canonical_abi_realloc`
1653
0
            // and `canonical_abi_free` functions that do the right thing).
1654
0
            //
1655
0
            // This is a pretty serious limitation of `wasm-smith`'s component
1656
0
            // types support, but it is one we are intentionally
1657
0
            // accepting. `wasm-smith` will focus on generating arbitrary
1658
0
            // component sections, structures, and import/export topologies; not
1659
0
            // component functions and core Wasm implementations of component
1660
0
            // functions. In the future, we intend to build a new, distinct test
1661
0
            // case generator specifically for exercising component functions
1662
0
            // and the canonical ABI. This new generator won't emit arbitrary
1663
0
            // component sections, structures, or import/export topologies, and
1664
0
            // will instead leave that to `wasm-smith`.
1665
0
1666
0
            if !self.component().scalar_component_funcs.is_empty() {
1667
0
                choices.push(|u, c| {
1668
0
                    let func_index = *u.choose(&c.component().scalar_component_funcs)?;
1669
0
                    Ok(Some(Func::CanonLower {
1670
0
                        // Scalar component functions don't use any canonical options.
1671
0
                        options: vec![],
1672
0
                        func_index,
1673
0
                    }))
1674
0
                });
1675
0
            }
1676
1677
0
            if !self.component().core_funcs.is_empty() {
1678
0
                choices.push(|u, c| {
1679
0
                    let core_func_index = u.int_in_range(
1680
0
                        0..=u32::try_from(c.component().core_funcs.len() - 1).unwrap(),
1681
0
                    )?;
1682
0
                    let core_func_ty = c.core_function_type(core_func_index);
1683
0
                    let comp_func_ty = inverse_scalar_canonical_abi_for(u, core_func_ty)?;
1684
1685
0
                    let func_ty = if let Some(indices) = c
1686
0
                        .current_type_scope()
1687
0
                        .func_type_to_indices
1688
0
                        .get(&comp_func_ty)
1689
                    {
1690
                        // If we've already defined this component function type
1691
                        // one or more times, then choose one of those
1692
                        // definitions arbitrarily.
1693
0
                        debug_assert!(!indices.is_empty());
1694
0
                        *u.choose(indices)?
1695
0
                    } else if c.current_type_scope().types.len() < c.config.max_types {
1696
                        // If we haven't already defined this component function
1697
                        // type, and we haven't defined the configured maximum
1698
                        // amount of types yet, then just define this type.
1699
0
                        let ty = Rc::new(Type::Func(Rc::new(comp_func_ty)));
1700
0
                        c.push_type(ty)
1701
                    } else {
1702
                        // Otherwise, give up on lifting this function.
1703
0
                        return Ok(None);
1704
                    };
1705
1706
0
                    Ok(Some(Func::CanonLift {
1707
0
                        func_ty,
1708
0
                        // Scalar functions don't use any canonical options.
1709
0
                        options: vec![],
1710
0
                        core_func_index,
1711
0
                    }))
1712
0
                });
1713
0
            }
1714
1715
0
            if choices.is_empty() {
1716
0
                return Ok(false);
1717
0
            }
1718
1719
0
            let f = u.choose(&choices)?;
1720
0
            if let Some(func) = f(u, self)? {
1721
0
                self.push_func(func);
1722
0
            }
1723
1724
0
            Ok(true)
1725
0
        })?;
1726
1727
0
        Ok(Step::StillBuilding)
1728
0
    }
1729
1730
0
    fn arbitrary_core_module_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1731
0
        let module = crate::core::Module::new_internal(
1732
0
            self.config.clone(),
1733
0
            u,
1734
0
            crate::core::DuplicateImportsBehavior::Disallowed,
1735
0
        )?;
1736
0
        self.push_section(Section::CoreModule(module));
1737
0
        self.total_modules += 1;
1738
0
        Ok(Step::StillBuilding)
1739
0
    }
1740
1741
0
    fn arbitrary_component_section(&mut self, u: &mut Unstructured) -> Result<Step> {
1742
0
        self.types.push(TypesScope::default());
1743
0
        self.components.push(ComponentContext::empty());
1744
0
        self.total_components += 1;
1745
0
        Ok(Step::StillBuilding)
1746
0
    }
1747
1748
0
    fn arbitrary_instance_section(&mut self, u: &mut Unstructured) -> Result<()> {
1749
0
        todo!()
1750
    }
1751
1752
0
    fn arbitrary_export_section(&mut self, u: &mut Unstructured) -> Result<()> {
1753
0
        todo!()
1754
    }
1755
1756
0
    fn arbitrary_start_section(&mut self, u: &mut Unstructured) -> Result<()> {
1757
0
        todo!()
1758
    }
1759
1760
0
    fn arbitrary_alias_section(&mut self, u: &mut Unstructured) -> Result<()> {
1761
0
        todo!()
1762
    }
1763
}
1764
1765
0
fn canonical_abi_for(func_ty: &FuncType) -> Rc<crate::core::FuncType> {
1766
0
    let to_core_ty = |ty| match ty {
1767
0
        ComponentValType::Primitive(prim_ty) => match prim_ty {
1768
            PrimitiveValType::Char
1769
            | PrimitiveValType::Bool
1770
            | PrimitiveValType::S8
1771
            | PrimitiveValType::U8
1772
            | PrimitiveValType::S16
1773
            | PrimitiveValType::U16
1774
            | PrimitiveValType::S32
1775
0
            | PrimitiveValType::U32 => ValType::I32,
1776
0
            PrimitiveValType::S64 | PrimitiveValType::U64 => ValType::I64,
1777
0
            PrimitiveValType::F32 => ValType::F32,
1778
0
            PrimitiveValType::F64 => ValType::F64,
1779
            PrimitiveValType::String => {
1780
0
                unimplemented!("non-scalar types are not supported yet")
1781
            }
1782
        },
1783
0
        ComponentValType::Type(_) => unimplemented!("non-scalar types are not supported yet"),
1784
0
    };
1785
1786
0
    Rc::new(crate::core::FuncType {
1787
0
        params: func_ty
1788
0
            .params
1789
0
            .iter()
1790
0
            .map(|(_, ty)| to_core_ty(*ty))
1791
0
            .collect(),
1792
0
        results: func_ty
1793
0
            .results
1794
0
            .iter()
1795
0
            .map(|(_, ty)| to_core_ty(*ty))
1796
0
            .collect(),
1797
0
    })
1798
0
}
1799
1800
0
fn inverse_scalar_canonical_abi_for(
1801
0
    u: &mut Unstructured,
1802
0
    core_func_ty: &crate::core::FuncType,
1803
0
) -> Result<FuncType> {
1804
0
    let from_core_ty = |u: &mut Unstructured, core_ty| match core_ty {
1805
0
        ValType::I32 => u
1806
0
            .choose(&[
1807
0
                ComponentValType::Primitive(PrimitiveValType::Char),
1808
0
                ComponentValType::Primitive(PrimitiveValType::Bool),
1809
0
                ComponentValType::Primitive(PrimitiveValType::S8),
1810
0
                ComponentValType::Primitive(PrimitiveValType::U8),
1811
0
                ComponentValType::Primitive(PrimitiveValType::S16),
1812
0
                ComponentValType::Primitive(PrimitiveValType::U16),
1813
0
                ComponentValType::Primitive(PrimitiveValType::S32),
1814
0
                ComponentValType::Primitive(PrimitiveValType::U32),
1815
0
            ])
1816
0
            .cloned(),
1817
0
        ValType::I64 => u
1818
0
            .choose(&[
1819
0
                ComponentValType::Primitive(PrimitiveValType::S64),
1820
0
                ComponentValType::Primitive(PrimitiveValType::U64),
1821
0
            ])
1822
0
            .cloned(),
1823
0
        ValType::F32 => Ok(ComponentValType::Primitive(PrimitiveValType::F32)),
1824
0
        ValType::F64 => Ok(ComponentValType::Primitive(PrimitiveValType::F64)),
1825
        ValType::V128 | ValType::Ref(_) => {
1826
0
            unreachable!("not used in canonical ABI")
1827
        }
1828
0
    };
1829
1830
0
    let mut names = HashSet::default();
1831
0
    let mut params = vec![];
1832
1833
0
    for core_ty in &core_func_ty.params {
1834
0
        params.push((
1835
0
            crate::unique_kebab_string(100, &mut names, u)?,
1836
0
            from_core_ty(u, *core_ty)?,
1837
        ));
1838
    }
1839
1840
0
    names.clear();
1841
1842
0
    let results = match core_func_ty.results.len() {
1843
0
        0 => Vec::new(),
1844
0
        1 => vec![(
1845
0
            if u.arbitrary()? {
1846
0
                Some(crate::unique_kebab_string(100, &mut names, u)?)
1847
            } else {
1848
0
                None
1849
            },
1850
0
            from_core_ty(u, core_func_ty.results[0])?,
1851
        )],
1852
0
        _ => unimplemented!("non-scalar types are not supported yet"),
1853
    };
1854
1855
0
    Ok(FuncType { params, results })
1856
0
}
1857
1858
#[derive(Debug)]
1859
enum Section {
1860
    Custom(CustomSection),
1861
    CoreModule(crate::Module),
1862
    CoreInstance(CoreInstanceSection),
1863
    CoreType(CoreTypeSection),
1864
    Component(Component),
1865
    Instance(InstanceSection),
1866
    Alias(AliasSection),
1867
    Type(TypeSection),
1868
    Canonical(CanonicalSection),
1869
    Start(StartSection),
1870
    Import(ImportSection),
1871
    Export(ExportSection),
1872
}
1873
1874
#[derive(Debug)]
1875
struct CustomSection {
1876
    name: String,
1877
    data: Vec<u8>,
1878
}
1879
1880
impl<'a> Arbitrary<'a> for CustomSection {
1881
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
1882
0
        let name = crate::limited_string(1_000, u)?;
1883
0
        let data = u.arbitrary()?;
1884
0
        Ok(CustomSection { name, data })
1885
0
    }
1886
}
1887
1888
#[derive(Debug)]
1889
struct TypeSection {
1890
    types: Vec<Rc<Type>>,
1891
}
1892
1893
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1894
enum CoreType {
1895
    Func(Rc<crate::core::FuncType>),
1896
    Module(Rc<ModuleType>),
1897
}
1898
1899
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
1900
struct ModuleType {
1901
    defs: Vec<ModuleTypeDef>,
1902
    has_memory: bool,
1903
    has_canonical_abi_realloc: bool,
1904
    has_canonical_abi_free: bool,
1905
}
1906
1907
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1908
enum ModuleTypeDef {
1909
    TypeDef(crate::core::CompositeType),
1910
    Import(crate::core::Import),
1911
    OuterAlias {
1912
        count: u32,
1913
        i: u32,
1914
        kind: CoreOuterAliasKind,
1915
    },
1916
    Export(String, crate::core::EntityType),
1917
}
1918
1919
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1920
enum Type {
1921
    Defined(DefinedType),
1922
    Func(Rc<FuncType>),
1923
    Component(Rc<ComponentType>),
1924
    Instance(Rc<InstanceType>),
1925
}
1926
1927
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1928
enum CoreInstanceExportAliasKind {
1929
    Func,
1930
    Table,
1931
    Memory,
1932
    Global,
1933
    Tag,
1934
}
1935
1936
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1937
enum CoreOuterAliasKind {
1938
    Type(Rc<crate::core::FuncType>),
1939
}
1940
1941
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1942
enum Alias {
1943
    InstanceExport {
1944
        instance: u32,
1945
        name: String,
1946
        kind: InstanceExportAliasKind,
1947
    },
1948
    CoreInstanceExport {
1949
        instance: u32,
1950
        name: String,
1951
        kind: CoreInstanceExportAliasKind,
1952
    },
1953
    Outer {
1954
        count: u32,
1955
        i: u32,
1956
        kind: OuterAliasKind,
1957
    },
1958
}
1959
1960
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1961
enum InstanceExportAliasKind {
1962
    Module,
1963
    Component,
1964
    Instance,
1965
    Func,
1966
    Value,
1967
}
1968
1969
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1970
enum OuterAliasKind {
1971
    Module,
1972
    Component,
1973
    CoreType(Rc<CoreType>),
1974
    Type(Rc<Type>),
1975
}
1976
1977
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1978
struct ComponentType {
1979
    defs: Vec<ComponentTypeDef>,
1980
}
1981
1982
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
1983
enum ComponentTypeDef {
1984
    CoreType(Rc<CoreType>),
1985
    Type(Rc<Type>),
1986
    Alias(Alias),
1987
    Import(Import),
1988
    Export {
1989
        name: String,
1990
        url: Option<String>,
1991
        ty: ComponentTypeRef,
1992
    },
1993
}
1994
1995
impl From<InstanceTypeDecl> for ComponentTypeDef {
1996
0
    fn from(def: InstanceTypeDecl) -> Self {
1997
0
        match def {
1998
0
            InstanceTypeDecl::CoreType(t) => Self::CoreType(t),
1999
0
            InstanceTypeDecl::Type(t) => Self::Type(t),
2000
0
            InstanceTypeDecl::Export { name, url, ty } => Self::Export { name, url, ty },
2001
0
            InstanceTypeDecl::Alias(a) => Self::Alias(a),
2002
        }
2003
0
    }
2004
}
2005
2006
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2007
struct InstanceType {
2008
    defs: Vec<InstanceTypeDecl>,
2009
}
2010
2011
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2012
enum InstanceTypeDecl {
2013
    CoreType(Rc<CoreType>),
2014
    Type(Rc<Type>),
2015
    Alias(Alias),
2016
    Export {
2017
        name: String,
2018
        url: Option<String>,
2019
        ty: ComponentTypeRef,
2020
    },
2021
}
2022
2023
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2024
struct FuncType {
2025
    params: Vec<(String, ComponentValType)>,
2026
    results: Vec<(Option<String>, ComponentValType)>,
2027
}
2028
2029
impl FuncType {
2030
0
    fn unnamed_result_ty(&self) -> Option<ComponentValType> {
2031
0
        if self.results.len() == 1 {
2032
0
            let (name, ty) = &self.results[0];
2033
0
            if name.is_none() {
2034
0
                return Some(*ty);
2035
0
            }
2036
0
        }
2037
0
        None
2038
0
    }
2039
2040
0
    fn is_scalar(&self) -> bool {
2041
0
        self.params.iter().all(|(_, ty)| is_scalar(ty))
2042
0
            && self.results.len() == 1
2043
0
            && is_scalar(&self.results[0].1)
2044
0
    }
2045
}
2046
2047
0
fn is_scalar(ty: &ComponentValType) -> bool {
2048
0
    match ty {
2049
0
        ComponentValType::Primitive(prim) => match prim {
2050
            PrimitiveValType::Bool
2051
            | PrimitiveValType::S8
2052
            | PrimitiveValType::U8
2053
            | PrimitiveValType::S16
2054
            | PrimitiveValType::U16
2055
            | PrimitiveValType::S32
2056
            | PrimitiveValType::U32
2057
            | PrimitiveValType::S64
2058
            | PrimitiveValType::U64
2059
            | PrimitiveValType::F32
2060
            | PrimitiveValType::F64
2061
0
            | PrimitiveValType::Char => true,
2062
0
            PrimitiveValType::String => false,
2063
        },
2064
0
        ComponentValType::Type(_) => false,
2065
    }
2066
0
}
2067
2068
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2069
enum DefinedType {
2070
    Primitive(PrimitiveValType),
2071
    Record(RecordType),
2072
    Variant(VariantType),
2073
    List(ListType),
2074
    Tuple(TupleType),
2075
    Flags(FlagsType),
2076
    Enum(EnumType),
2077
    Option(OptionType),
2078
    Result(ResultType),
2079
}
2080
2081
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2082
struct RecordType {
2083
    fields: Vec<(String, ComponentValType)>,
2084
}
2085
2086
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2087
struct VariantType {
2088
    cases: Vec<(String, Option<ComponentValType>, Option<u32>)>,
2089
}
2090
2091
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2092
struct ListType {
2093
    elem_ty: ComponentValType,
2094
}
2095
2096
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2097
struct TupleType {
2098
    fields: Vec<ComponentValType>,
2099
}
2100
2101
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2102
struct FlagsType {
2103
    fields: Vec<String>,
2104
}
2105
2106
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2107
struct EnumType {
2108
    variants: Vec<String>,
2109
}
2110
2111
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2112
struct OptionType {
2113
    inner_ty: ComponentValType,
2114
}
2115
2116
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2117
struct ResultType {
2118
    ok_ty: Option<ComponentValType>,
2119
    err_ty: Option<ComponentValType>,
2120
}
2121
2122
#[derive(Debug)]
2123
struct ImportSection {
2124
    imports: Vec<Import>,
2125
}
2126
2127
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
2128
struct Import {
2129
    name: String,
2130
    url: Option<String>,
2131
    ty: ComponentTypeRef,
2132
}
2133
2134
#[derive(Debug)]
2135
struct CanonicalSection {
2136
    funcs: Vec<Func>,
2137
}
2138
2139
#[derive(Debug)]
2140
enum Func {
2141
    CanonLift {
2142
        func_ty: u32,
2143
        options: Vec<CanonOpt>,
2144
        core_func_index: u32,
2145
    },
2146
    CanonLower {
2147
        options: Vec<CanonOpt>,
2148
        func_index: u32,
2149
    },
2150
}
2151
2152
#[derive(Debug)]
2153
enum CanonOpt {
2154
    StringUtf8,
2155
    StringUtf16,
2156
    StringLatin1Utf16,
2157
    Memory(u32),
2158
    Realloc(u32),
2159
    PostReturn(u32),
2160
}
2161
2162
#[derive(Debug)]
2163
struct InstanceSection {}
2164
2165
#[derive(Debug)]
2166
struct ExportSection {}
2167
2168
#[derive(Debug)]
2169
struct StartSection {}
2170
2171
#[derive(Debug)]
2172
struct AliasSection {}
2173
2174
#[derive(Debug)]
2175
struct CoreInstanceSection {}
2176
2177
#[derive(Debug)]
2178
struct CoreTypeSection {
2179
    types: Vec<Rc<CoreType>>,
2180
}
2181
2182
0
fn arbitrary_func_type(
2183
0
    u: &mut Unstructured,
2184
0
    config: &Config,
2185
0
    valtypes: &[ValType],
2186
0
    max_results: Option<usize>,
2187
0
    type_ref_limit: u32,
2188
0
) -> Result<Rc<crate::core::FuncType>> {
2189
0
    let mut params = vec![];
2190
0
    let mut results = vec![];
2191
0
    arbitrary_loop(u, 0, 20, |u| {
2192
0
        params.push(arbitrary_valtype(u, config, valtypes, type_ref_limit)?);
2193
0
        Ok(true)
2194
0
    })?;
2195
0
    arbitrary_loop(u, 0, max_results.unwrap_or(20), |u| {
2196
0
        results.push(arbitrary_valtype(u, config, valtypes, type_ref_limit)?);
2197
0
        Ok(true)
2198
0
    })?;
2199
0
    Ok(Rc::new(crate::core::FuncType { params, results }))
2200
0
}
2201
2202
0
fn arbitrary_valtype(
2203
0
    u: &mut Unstructured,
2204
0
    config: &Config,
2205
0
    valtypes: &[ValType],
2206
0
    type_ref_limit: u32,
2207
0
) -> Result<ValType> {
2208
0
    if config.gc_enabled && type_ref_limit > 0 && u.ratio(1, 20)? {
2209
        Ok(ValType::Ref(RefType {
2210
            // TODO: For now, only create allow nullable reference
2211
            // types. Eventually we should support non-nullable reference types,
2212
            // but this means that we will also need to recognize when it is
2213
            // impossible to create an instance of the reference (eg `(ref
2214
            // nofunc)` has no instances, and self-referential types that
2215
            // contain a non-null self-reference are also impossible to create).
2216
            nullable: true,
2217
0
            heap_type: HeapType::Concrete(u.int_in_range(0..=type_ref_limit - 1)?),
2218
        }))
2219
    } else {
2220
0
        Ok(*u.choose(valtypes)?)
2221
    }
2222
0
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/component/encode.rs
Line
Count
Source (jump to first uncovered line)
1
use std::borrow::Cow;
2
3
use super::*;
4
use wasm_encoder::{ComponentExportKind, ComponentOuterAliasKind, ExportKind};
5
6
impl Component {
7
    /// Encode this Wasm component into bytes.
8
0
    pub fn to_bytes(&self) -> Vec<u8> {
9
0
        self.encoded().finish()
10
0
    }
11
12
0
    fn encoded(&self) -> wasm_encoder::Component {
13
0
        let mut component = wasm_encoder::Component::new();
14
0
        for section in &self.sections {
15
0
            section.encode(&mut component);
16
0
        }
17
0
        component
18
0
    }
19
}
20
21
impl Section {
22
0
    fn encode(&self, component: &mut wasm_encoder::Component) {
23
0
        match self {
24
0
            Self::Custom(sec) => sec.encode(component),
25
0
            Self::CoreModule(module) => {
26
0
                let bytes = module.to_bytes();
27
0
                component.section(&wasm_encoder::RawSection {
28
0
                    id: wasm_encoder::ComponentSectionId::CoreModule as u8,
29
0
                    data: &bytes,
30
0
                });
31
0
            }
32
0
            Self::CoreInstance(_) => todo!(),
33
0
            Self::CoreType(sec) => sec.encode(component),
34
0
            Self::Component(comp) => {
35
0
                let bytes = comp.to_bytes();
36
0
                component.section(&wasm_encoder::RawSection {
37
0
                    id: wasm_encoder::ComponentSectionId::Component as u8,
38
0
                    data: &bytes,
39
0
                });
40
0
            }
41
0
            Self::Instance(_) => todo!(),
42
0
            Self::Alias(_) => todo!(),
43
0
            Self::Type(sec) => sec.encode(component),
44
0
            Self::Canonical(sec) => sec.encode(component),
45
0
            Self::Start(_) => todo!(),
46
0
            Self::Import(sec) => sec.encode(component),
47
0
            Self::Export(_) => todo!(),
48
        }
49
0
    }
50
}
51
52
impl CustomSection {
53
0
    fn encode(&self, component: &mut wasm_encoder::Component) {
54
0
        component.section(&wasm_encoder::CustomSection {
55
0
            name: (&self.name).into(),
56
0
            data: Cow::Borrowed(&self.data),
57
0
        });
58
0
    }
59
}
60
61
impl TypeSection {
62
0
    fn encode(&self, component: &mut wasm_encoder::Component) {
63
0
        let mut sec = wasm_encoder::ComponentTypeSection::new();
64
0
        for ty in &self.types {
65
0
            ty.encode(sec.ty());
66
0
        }
67
0
        component.section(&sec);
68
0
    }
69
}
70
71
impl ImportSection {
72
0
    fn encode(&self, component: &mut wasm_encoder::Component) {
73
0
        let mut sec = wasm_encoder::ComponentImportSection::new();
74
0
        for imp in &self.imports {
75
0
            sec.import(&imp.name, imp.ty);
76
0
        }
77
0
        component.section(&sec);
78
0
    }
79
}
80
81
impl CanonicalSection {
82
0
    fn encode(&self, component: &mut wasm_encoder::Component) {
83
0
        let mut sec = wasm_encoder::CanonicalFunctionSection::new();
84
0
        for func in &self.funcs {
85
0
            match func {
86
                Func::CanonLift {
87
0
                    func_ty,
88
0
                    options,
89
0
                    core_func_index,
90
0
                } => {
91
0
                    let options = translate_canon_opt(options);
92
0
                    sec.lift(*core_func_index, *func_ty, options);
93
0
                }
94
                Func::CanonLower {
95
0
                    options,
96
0
                    func_index,
97
0
                } => {
98
0
                    let options = translate_canon_opt(options);
99
0
                    sec.lower(*func_index, options);
100
0
                }
101
            }
102
        }
103
0
        component.section(&sec);
104
0
    }
105
}
106
107
impl CoreTypeSection {
108
0
    fn encode(&self, component: &mut wasm_encoder::Component) {
109
0
        let mut sec = wasm_encoder::CoreTypeSection::new();
110
0
        for ty in &self.types {
111
0
            ty.encode(sec.ty());
112
0
        }
113
0
        component.section(&sec);
114
0
    }
115
}
116
117
impl CoreType {
118
0
    fn encode(&self, enc: wasm_encoder::CoreTypeEncoder<'_>) {
119
0
        match self {
120
0
            Self::Func(ty) => {
121
0
                enc.function(ty.params.iter().copied(), ty.results.iter().copied());
122
0
            }
123
0
            Self::Module(mod_ty) => {
124
0
                let mut enc_mod_ty = wasm_encoder::ModuleType::new();
125
0
                for def in &mod_ty.defs {
126
0
                    match def {
127
0
                        ModuleTypeDef::TypeDef(crate::core::CompositeType::Func(func_ty)) => {
128
0
                            enc_mod_ty.ty().function(
129
0
                                func_ty.params.iter().copied(),
130
0
                                func_ty.results.iter().copied(),
131
0
                            );
132
0
                        }
133
                        ModuleTypeDef::TypeDef(_) => {
134
0
                            unimplemented!("non-func types in a component's module type")
135
                        }
136
0
                        ModuleTypeDef::OuterAlias { count, i, kind } => match kind {
137
0
                            CoreOuterAliasKind::Type(_) => {
138
0
                                enc_mod_ty.alias_outer_core_type(*count, *i);
139
0
                            }
140
                        },
141
0
                        ModuleTypeDef::Import(imp) => {
142
0
                            enc_mod_ty.import(
143
0
                                &imp.module,
144
0
                                &imp.field,
145
0
                                crate::core::encode::translate_entity_type(&imp.entity_type),
146
0
                            );
147
0
                        }
148
0
                        ModuleTypeDef::Export(name, ty) => {
149
0
                            enc_mod_ty.export(name, crate::core::encode::translate_entity_type(ty));
150
0
                        }
151
                    }
152
                }
153
0
                enc.module(&enc_mod_ty);
154
            }
155
        }
156
0
    }
157
}
158
159
impl Type {
160
0
    fn encode(&self, enc: wasm_encoder::ComponentTypeEncoder<'_>) {
161
0
        match self {
162
0
            Self::Defined(ty) => {
163
0
                ty.encode(enc.defined_type());
164
0
            }
165
0
            Self::Func(func_ty) => {
166
0
                let mut f = enc.function();
167
0
168
0
                f.params(func_ty.params.iter().map(|(name, ty)| (name.as_str(), *ty)));
169
170
0
                if let Some(ty) = func_ty.unnamed_result_ty() {
171
0
                    f.result(ty);
172
0
                } else {
173
0
                    f.results(
174
0
                        func_ty
175
0
                            .results
176
0
                            .iter()
177
0
                            .map(|(name, ty)| (name.as_deref().unwrap(), *ty)),
178
0
                    );
179
0
                }
180
            }
181
0
            Self::Component(comp_ty) => {
182
0
                let mut enc_comp_ty = wasm_encoder::ComponentType::new();
183
0
                for def in &comp_ty.defs {
184
0
                    match def {
185
0
                        ComponentTypeDef::Import(imp) => {
186
0
                            enc_comp_ty.import(&imp.name, imp.ty);
187
0
                        }
188
0
                        ComponentTypeDef::CoreType(ty) => {
189
0
                            ty.encode(enc_comp_ty.core_type());
190
0
                        }
191
0
                        ComponentTypeDef::Type(ty) => {
192
0
                            ty.encode(enc_comp_ty.ty());
193
0
                        }
194
0
                        ComponentTypeDef::Export { name, url: _, ty } => {
195
0
                            enc_comp_ty.export(name, *ty);
196
0
                        }
197
0
                        ComponentTypeDef::Alias(a) => {
198
0
                            enc_comp_ty.alias(translate_alias(a));
199
0
                        }
200
                    }
201
                }
202
0
                enc.component(&enc_comp_ty);
203
            }
204
0
            Self::Instance(inst_ty) => {
205
0
                let mut enc_inst_ty = wasm_encoder::InstanceType::new();
206
0
                for def in &inst_ty.defs {
207
0
                    match def {
208
0
                        InstanceTypeDecl::CoreType(ty) => {
209
0
                            ty.encode(enc_inst_ty.core_type());
210
0
                        }
211
0
                        InstanceTypeDecl::Type(ty) => {
212
0
                            ty.encode(enc_inst_ty.ty());
213
0
                        }
214
0
                        InstanceTypeDecl::Export { name, url: _, ty } => {
215
0
                            enc_inst_ty.export(name, *ty);
216
0
                        }
217
0
                        InstanceTypeDecl::Alias(a) => {
218
0
                            enc_inst_ty.alias(translate_alias(a));
219
0
                        }
220
                    }
221
                }
222
0
                enc.instance(&enc_inst_ty);
223
            }
224
        }
225
0
    }
226
}
227
228
impl DefinedType {
229
0
    fn encode(&self, enc: wasm_encoder::ComponentDefinedTypeEncoder<'_>) {
230
0
        match self {
231
0
            Self::Primitive(ty) => enc.primitive(*ty),
232
0
            Self::Record(ty) => {
233
0
                enc.record(ty.fields.iter().map(|(name, ty)| (name.as_str(), *ty)));
234
0
            }
235
0
            Self::Variant(ty) => {
236
0
                enc.variant(
237
0
                    ty.cases
238
0
                        .iter()
239
0
                        .map(|(name, ty, refines)| (name.as_str(), *ty, *refines)),
240
0
                );
241
0
            }
242
0
            Self::List(ty) => {
243
0
                enc.list(ty.elem_ty);
244
0
            }
245
0
            Self::Tuple(ty) => {
246
0
                enc.tuple(ty.fields.iter().copied());
247
0
            }
248
0
            Self::Flags(ty) => {
249
0
                enc.flags(ty.fields.iter().map(|f| f.as_str()));
250
0
            }
251
0
            Self::Enum(ty) => {
252
0
                enc.enum_type(ty.variants.iter().map(|v| v.as_str()));
253
0
            }
254
0
            Self::Option(ty) => {
255
0
                enc.option(ty.inner_ty);
256
0
            }
257
0
            Self::Result(ty) => {
258
0
                enc.result(ty.ok_ty, ty.err_ty);
259
0
            }
260
        }
261
0
    }
262
}
263
264
0
fn translate_canon_opt(options: &[CanonOpt]) -> Vec<wasm_encoder::CanonicalOption> {
265
0
    options
266
0
        .iter()
267
0
        .map(|o| match o {
268
0
            CanonOpt::StringUtf8 => wasm_encoder::CanonicalOption::UTF8,
269
0
            CanonOpt::StringUtf16 => wasm_encoder::CanonicalOption::UTF16,
270
0
            CanonOpt::StringLatin1Utf16 => wasm_encoder::CanonicalOption::CompactUTF16,
271
0
            CanonOpt::Memory(idx) => wasm_encoder::CanonicalOption::Memory(*idx),
272
0
            CanonOpt::Realloc(idx) => wasm_encoder::CanonicalOption::Realloc(*idx),
273
0
            CanonOpt::PostReturn(idx) => wasm_encoder::CanonicalOption::PostReturn(*idx),
274
0
        })
275
0
        .collect()
276
0
}
277
278
0
fn translate_alias(alias: &Alias) -> wasm_encoder::Alias<'_> {
279
0
    match alias {
280
        Alias::InstanceExport {
281
0
            instance,
282
0
            name,
283
0
            kind,
284
0
        } => wasm_encoder::Alias::InstanceExport {
285
0
            instance: *instance,
286
0
            name,
287
0
            kind: match kind {
288
0
                InstanceExportAliasKind::Module => ComponentExportKind::Module,
289
0
                InstanceExportAliasKind::Component => ComponentExportKind::Component,
290
0
                InstanceExportAliasKind::Instance => ComponentExportKind::Instance,
291
0
                InstanceExportAliasKind::Func => ComponentExportKind::Func,
292
0
                InstanceExportAliasKind::Value => ComponentExportKind::Value,
293
            },
294
        },
295
        Alias::CoreInstanceExport {
296
0
            instance,
297
0
            name,
298
0
            kind,
299
0
        } => wasm_encoder::Alias::CoreInstanceExport {
300
0
            instance: *instance,
301
0
            name,
302
0
            kind: match kind {
303
0
                CoreInstanceExportAliasKind::Func => ExportKind::Func,
304
0
                CoreInstanceExportAliasKind::Table => ExportKind::Table,
305
0
                CoreInstanceExportAliasKind::Global => ExportKind::Global,
306
0
                CoreInstanceExportAliasKind::Memory => ExportKind::Memory,
307
0
                CoreInstanceExportAliasKind::Tag => ExportKind::Tag,
308
            },
309
        },
310
0
        Alias::Outer { count, i, kind } => wasm_encoder::Alias::Outer {
311
0
            count: *count,
312
0
            index: *i,
313
0
            kind: match kind {
314
0
                OuterAliasKind::Module => ComponentOuterAliasKind::CoreModule,
315
0
                OuterAliasKind::Component => ComponentOuterAliasKind::Component,
316
0
                OuterAliasKind::Type(_) => ComponentOuterAliasKind::Type,
317
0
                OuterAliasKind::CoreType(_) => ComponentOuterAliasKind::CoreType,
318
            },
319
        },
320
    }
321
0
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/config.rs
Line
Count
Source (jump to first uncovered line)
1
//! Configuring the shape of generated Wasm modules.
2
3
use crate::InstructionKinds;
4
use arbitrary::{Arbitrary, Result, Unstructured};
5
6
macro_rules! define_config {
7
    (
8
        $(#[$attr:meta])*
9
        pub struct Config {
10
            $(
11
                $(#[$field_attr:meta])*
12
                pub $field:ident : $field_ty:ty = $default:expr,
13
            )*
14
        }
15
    ) => {
16
        $(#[$attr])*
17
        pub struct Config {
18
            /// The imports that may be used when generating the module.
19
            ///
20
            /// Defaults to `None` which means that any arbitrary import can be
21
            /// generated.
22
            ///
23
            /// To only allow specific imports, set this field to a WebAssembly
24
            /// module which describes the imports allowed.
25
            ///
26
            /// Note that [`Self::min_imports`] is ignored when
27
            /// `available_imports` are enabled.
28
            ///
29
            /// The provided value must be a valid binary encoding of a
30
            /// WebAssembly module. `wasm-smith` will panic if the module cannot
31
            /// be parsed.
32
            ///
33
            /// # Example
34
            ///
35
            /// An implementation of this method could use the `wat` crate to
36
            /// provide a human-readable and maintainable description:
37
            ///
38
            /// ```rust
39
            /// Some(wat::parse_str(r#"
40
            ///     (module
41
            ///         (import "env" "ping" (func (param i32)))
42
            ///         (import "env" "pong" (func (result i32)))
43
            ///         (import "env" "memory" (memory 1))
44
            ///         (import "env" "table" (table 1))
45
            ///         (import "env" "tag" (tag (param i32)))
46
            ///     )
47
            /// "#))
48
            /// # ;
49
            /// ```
50
            pub available_imports: Option<Vec<u8>>,
51
52
            /// If provided, the generated module will have exports with exactly
53
            /// the same names and types as those in the provided WebAssembly
54
            /// module. The implementation (e.g. function bodies, global
55
            /// initializers) of each export in the generated module will be
56
            /// random and unrelated to the implementation in the provided
57
            /// module. Only globals and functions are supported.
58
            ///
59
            ///
60
            /// Defaults to `None` which means arbitrary exports will be
61
            /// generated.
62
            ///
63
            /// To specify which exports the generated modules should have, set
64
            /// this field to a WebAssembly module which describes the desired
65
            /// exports. To generate modules with varying exports that meet some
66
            /// constraints, consider randomly generating the value for this
67
            /// field.
68
            ///
69
            /// The provided value must be a valid binary encoding of a
70
            /// WebAssembly module. `wasm-smith` will panic if the module cannot
71
            /// be parsed.
72
            ///
73
            /// # Module Limits
74
            ///
75
            /// All types, functions, globals, and exports that are needed to
76
            /// provide the required exports will be generated, even if it
77
            /// causes the resulting module to exceed the limits defined in
78
            /// [`Self::max_type_size`], [`Self::max_types`],
79
            /// [`Self::max_funcs`], [`Self::max_globals`], or
80
            /// [`Self::max_exports`].
81
            ///
82
            /// # Example
83
            ///
84
            /// As for [`Self::available_imports`], the `wat` crate can be used
85
            /// to provide an human-readable description of the desired exports:
86
            ///
87
            /// ```rust
88
            /// Some(wat::parse_str(r#"
89
            ///     (module
90
            ///         (func (export "foo") (param i32) (result i64) unreachable)
91
            ///         (global (export "bar") f32 f32.const 0)
92
            ///     )
93
            /// "#));
94
            /// ```
95
            pub exports: Option<Vec<u8>>,
96
97
            $(
98
                $(#[$field_attr])*
99
                pub $field: $field_ty,
100
            )*
101
        }
102
103
        impl Default for Config {
104
5.67k
            fn default() -> Config {
105
5.67k
                Config {
106
5.67k
                    available_imports: None,
107
5.67k
                    exports: None,
108
5.67k
109
5.67k
                    $(
110
5.67k
                        $field: $default,
111
5.67k
                    )*
112
5.67k
                }
113
5.67k
            }
114
        }
115
116
        #[cfg(feature = "_internal_cli")]
117
        #[doc(hidden)]
118
        #[derive(Clone, Debug, Default, clap::Parser, serde_derive::Deserialize)]
119
        #[serde(rename_all = "kebab-case")]
120
        pub struct InternalOptionalConfig {
121
            /// The imports that may be used when generating the module.
122
            ///
123
            /// When unspecified, any arbitrary import can be generated.
124
            ///
125
            /// To only allow specific imports, provide a file path of a
126
            /// WebAssembly module which describes the imports allowed.
127
            ///
128
            /// Note that [`Self::min_imports`] is ignored when
129
            /// `available_imports` are enabled.
130
            ///
131
            /// The provided value must be a valid binary encoding of a
132
            /// WebAssembly module. `wasm-smith` will panic if the module cannot
133
            /// be parsed.
134
            #[cfg_attr(feature = "clap", clap(long))]
135
            available_imports: Option<std::path::PathBuf>,
136
137
            /// If provided, the generated module will have exports with exactly
138
            /// the same names and types as those in the provided WebAssembly
139
            /// module. The implementation (e.g. function bodies, global
140
            /// initializers) of each export in the generated module will be
141
            /// random and unrelated to the implementation in the provided
142
            /// module. Only globals and functions are supported.
143
            ///
144
            /// Defaults to `None` which means arbitrary exports will be
145
            /// generated.
146
            ///
147
            /// To specify which exports the generated modules should have, set
148
            /// this field to a WebAssembly module which describes the desired
149
            /// exports. To generate modules with varying exports that meet some
150
            /// constraints, consider randomly generating the value for this
151
            /// field.
152
            ///
153
            /// The provided value must be a valid binary encoding of a
154
            /// WebAssembly module. `wasm-smith` will panic if the module cannot
155
            /// be parsed.
156
            ///
157
            /// # Module Limits
158
            ///
159
            /// All types, functions, globals, and exports that are needed to
160
            /// provide the required exports will be generated, even if it
161
            /// causes the resulting module to exceed the limits defined in
162
            /// [`Self::max_type_size`], [`Self::max_types`],
163
            /// [`Self::max_funcs`], [`Self::max_globals`], or
164
            /// [`Self::max_exports`].
165
            ///
166
            #[cfg_attr(feature = "clap", clap(long))]
167
            exports: Option<std::path::PathBuf>,
168
169
            $(
170
                $(#[$field_attr])*
171
                #[cfg_attr(feature = "clap", clap(long))]
172
                pub $field: Option<$field_ty>,
173
            )*
174
        }
175
176
        #[cfg(feature = "_internal_cli")]
177
        impl InternalOptionalConfig {
178
            pub fn or(self, other: Self) -> Self {
179
                Self {
180
                    available_imports: self.available_imports.or(other.available_imports),
181
                    exports: self.exports.or(other.exports),
182
183
                    $(
184
                        $field: self.$field.or(other.$field),
185
                    )*
186
                }
187
            }
188
        }
189
190
        #[cfg(feature = "_internal_cli")]
191
        impl TryFrom<InternalOptionalConfig> for Config {
192
            type Error = anyhow::Error;
193
            fn try_from(config: InternalOptionalConfig) -> anyhow::Result<Config> {
194
                let default = Config::default();
195
                Ok(Config {
196
                    available_imports: if let Some(file) = config
197
                        .available_imports
198
                        .as_ref() {
199
                            Some(wat::parse_file(file)?)
200
                        } else {
201
                            None
202
                        },
203
                    exports: if let Some(file) = config
204
                        .exports
205
                        .as_ref() {
206
                            Some(wat::parse_file(file)?)
207
                        } else {
208
                            None
209
                        },
210
211
                    $(
212
                        $field: config.$field.unwrap_or(default.$field),
213
                    )*
214
                })
215
            }
216
        }
217
    }
218
}
219
220
define_config! {
221
    /// Configuration for a generated module.
222
    ///
223
    /// Don't care to configure your generated modules? Just use
224
    /// [`Module::arbitrary`][crate::Module], which internally uses the default
225
    /// configuration.
226
    ///
227
    /// Want control over the shape of the module that gets generated? Create a
228
    /// `Config` and then pass it to [`Module::new`][crate::Module::new].
229
    ///
230
    /// # Swarm Testing
231
    ///
232
    /// You can use the `Arbitrary for Config` implementation for [swarm
233
    /// testing]. This will dynamically -- but still deterministically -- choose
234
    /// configuration options for you.
235
    ///
236
    /// [swarm testing]: https://www.cs.utah.edu/~regehr/papers/swarm12.pdf
237
    ///
238
    /// Note that we pick only *maximums*, not minimums, here because it is more
239
    /// complex to describe the domain of valid configs when minima are involved
240
    /// (`min <= max` for each variable) and minima are mostly used to ensure
241
    /// certain elements are present, but do not widen the range of generated
242
    /// Wasm modules.
243
    #[derive(Clone, Debug)]
244
    pub struct Config {
245
        /// Determines whether a `start` export may be included. Defaults to `true`.
246
        pub allow_start_export: bool = true,
247
248
        /// The kinds of instructions allowed in the generated wasm
249
        /// programs. Defaults to all.
250
        ///
251
        /// The categories of instructions match the categories used by the
252
        /// [WebAssembly
253
        /// specification](https://webassembly.github.io/spec/core/syntax/instructions.html);
254
        /// e.g., numeric, vector, control, memory, etc.
255
        ///
256
        /// Note that modifying this setting is separate from the proposal
257
        /// flags; that is, if `simd_enabled() == true` but
258
        /// `allowed_instruction()` does not include vector instructions, the
259
        /// generated programs will not include these instructions but could
260
        /// contain vector types.
261
        pub allowed_instructions: InstructionKinds = InstructionKinds::all(),
262
263
        /// Determines whether the bulk memory proposal is enabled for
264
        /// generating instructions.
265
        ///
266
        /// Defaults to `false`.
267
        pub bulk_memory_enabled: bool = false,
268
269
        /// Returns whether NaN values are canonicalized after all f32/f64
270
        /// operation. Defaults to false.
271
        ///
272
        /// This can be useful when a generated wasm module is executed in
273
        /// multiple runtimes which may produce different NaN values. This
274
        /// ensures that the generated module will always use the same NaN
275
        /// representation for all instructions which have visible side effects,
276
        /// for example writing floats to memory or float-to-int bitcast
277
        /// instructions.
278
        pub canonicalize_nans: bool = false,
279
280
        /// Returns whether we should avoid generating code that will possibly
281
        /// trap.
282
        ///
283
        /// For some trapping instructions, this will emit extra instructions to
284
        /// ensure they don't trap, while some instructions will simply be
285
        /// excluded.  In cases where we would run into a trap, we instead
286
        /// choose some arbitrary non-trapping behavior. For example, if we
287
        /// detect that a Load instruction would attempt to access out-of-bounds
288
        /// memory, we instead pretend the load succeeded and push 0 onto the
289
        /// stack.
290
        ///
291
        /// One type of trap that we can't currently avoid is
292
        /// StackOverflow. Even when `disallow_traps` is set to true, wasm-smith
293
        /// will eventually generate a program that infinitely recurses, causing
294
        /// the call stack to be exhausted.
295
        ///
296
        /// Defaults to `false`.
297
        pub disallow_traps: bool = false,
298
299
        /// Determines whether the exception-handling proposal is enabled for
300
        /// generating instructions.
301
        ///
302
        /// Defaults to `false`.
303
        pub exceptions_enabled: bool = false,
304
305
        /// Export all WebAssembly objects in the module. Defaults to false.
306
        ///
307
        /// This overrides [`Config::min_exports`] and [`Config::max_exports`].
308
        pub export_everything: bool = false,
309
310
        /// Determines whether the GC proposal is enabled when generating a Wasm
311
        /// module.
312
        ///
313
        /// Defaults to `false`.
314
        pub gc_enabled: bool = false,
315
316
        /// Determines whether the custom-page-sizes proposal is enabled when
317
        /// generating a Wasm module.
318
        ///
319
        /// Defaults to `false`.
320
        pub custom_page_sizes_enabled: bool = false,
321
322
        /// Returns whether we should generate custom sections or not. Defaults
323
        /// to false.
324
        pub generate_custom_sections: bool = false,
325
326
        /// Returns the maximal size of the `alias` section. Defaults to 1000.
327
        pub max_aliases: usize = 1000,
328
329
        /// The maximum number of components to use. Defaults to 10.
330
        ///
331
        /// This includes imported components.
332
        ///
333
        /// Note that this is only relevant for components.
334
        pub max_components: usize = 10,
335
336
        /// The maximum number of data segments to generate. Defaults to 100.
337
        pub max_data_segments: usize = 100,
338
339
        /// The maximum number of element segments to generate. Defaults to 100.
340
        pub max_element_segments: usize = 100,
341
342
        /// The maximum number of elements within a segment to
343
        /// generate. Defaults to 100.
344
        pub max_elements: usize = 100,
345
346
        /// The maximum number of exports to generate. Defaults to 100.
347
        pub max_exports: usize = 100,
348
349
        /// The maximum number of functions to generate. Defaults to 100.  This
350
        /// includes imported functions.
351
        pub max_funcs: usize = 100,
352
353
        /// The maximum number of globals to generate. Defaults to 100.  This
354
        /// includes imported globals.
355
        pub max_globals: usize = 100,
356
357
        /// The maximum number of imports to generate. Defaults to 100.
358
        pub max_imports: usize = 100,
359
360
        /// The maximum number of instances to use. Defaults to 10.
361
        ///
362
        /// This includes imported instances.
363
        ///
364
        /// Note that this is only relevant for components.
365
        pub max_instances: usize = 10,
366
367
        /// The maximum number of instructions to generate in a function
368
        /// body. Defaults to 100.
369
        ///
370
        /// Note that some additional `end`s, `else`s, and `unreachable`s may be
371
        /// appended to the function body to finish block scopes.
372
        pub max_instructions: usize = 100,
373
374
        /// The maximum number of memories to use. Defaults to 1.
375
        ///
376
        /// This includes imported memories.
377
        ///
378
        /// Note that more than one memory is in the realm of the multi-memory
379
        /// wasm proposal.
380
        pub max_memories: usize = 1,
381
382
        /// The maximum, in 64k Wasm pages, of any 32-bit memory's initial or
383
        /// maximum size.
384
        ///
385
        /// Defaults to 2^16.
386
        pub max_memory32_pages: u64 = 1 << 16,
387
388
        /// The maximum, in 64k Wasm pages, of any 64-bit memory's initial or
389
        /// maximum size.
390
        ///
391
        /// Defaults to 2^48.
392
        pub max_memory64_pages: u64 = 1 << 48,
393
394
        /// The maximum number of modules to use. Defaults to 10.
395
        ///
396
        /// This includes imported modules.
397
        ///
398
        /// Note that this is only relevant for components.
399
        pub max_modules: usize = 10,
400
401
        /// Returns the maximal nesting depth of modules with the component
402
        /// model proposal. Defaults to 10.
403
        pub max_nesting_depth: usize = 10,
404
405
        /// The maximum, elements, of any table's initial or maximum
406
        /// size. Defaults to 1 million.
407
        pub max_table_elements: u64 = 1_000_000,
408
409
        /// The maximum number of tables to use. Defaults to 1.
410
        ///
411
        /// This includes imported tables.
412
        ///
413
        /// Note that more than one table is in the realm of the reference types
414
        /// proposal.
415
        pub max_tables: usize = 1,
416
417
        /// The maximum number of tags to generate. Defaults to 100.
418
        pub max_tags: usize = 100,
419
420
        /// Returns the maximal effective size of any type generated by
421
        /// wasm-smith.
422
        ///
423
        /// Note that this number is roughly in units of "how many types would
424
        /// be needed to represent the recursive type". A function with 8
425
        /// parameters and 2 results would take 11 types (one for the type, 10
426
        /// for params/results). A module type with 2 imports and 3 exports
427
        /// would take 6 (module + imports + exports) plus the size of each
428
        /// import/export type. This is a somewhat rough measurement that is not
429
        /// intended to be very precise.
430
        ///
431
        /// Defaults to 1000.
432
        pub max_type_size: u32 = 1000,
433
434
        /// The maximum number of types to generate. Defaults to 100.
435
        pub max_types: usize = 100,
436
437
        /// The maximum number of values to use. Defaults to 10.
438
        ///
439
        /// This includes imported values.
440
        ///
441
        /// Note that this is irrelevant unless value model support is enabled.
442
        pub max_values: usize = 10,
443
444
        /// Returns whether 64-bit memories are allowed. Defaults to false.
445
        ///
446
        /// Note that this is the gate for the memory64 proposal to WebAssembly.
447
        pub memory64_enabled: bool = false,
448
449
        /// Whether every Wasm memory must have a maximum size
450
        /// specified. Defaults to `false`.
451
        pub memory_max_size_required: bool = false,
452
453
        /// Control the probability of generating memory offsets that are in
454
        /// bounds vs. potentially out of bounds.
455
        ///
456
        /// See the `MemoryOffsetChoices` struct for details.
457
        pub memory_offset_choices: MemoryOffsetChoices = MemoryOffsetChoices::default(),
458
459
        /// The minimum number of data segments to generate. Defaults to 0.
460
        pub min_data_segments: usize = 0,
461
462
        /// The minimum number of element segments to generate. Defaults to 0.
463
        pub min_element_segments: usize = 0,
464
465
        /// The minimum number of elements within a segment to
466
        /// generate. Defaults to 0.
467
        pub min_elements: usize = 0,
468
469
        /// The minimum number of exports to generate. Defaults to 0.
470
        pub min_exports: usize = 0,
471
472
        /// The minimum number of functions to generate. Defaults to 0.
473
        ///
474
        /// This includes imported functions.
475
        pub min_funcs: usize = 0,
476
477
        /// The minimum number of globals to generate. Defaults to 0.
478
        ///
479
        /// This includes imported globals.
480
        pub min_globals: usize = 0,
481
482
        /// The minimum number of imports to generate. Defaults to 0.
483
        ///
484
        /// Note that if the sum of the maximum function[^1], table, global and
485
        /// memory counts is less than the minimum number of imports, then it
486
        /// will not be possible to satisfy all constraints (because imports
487
        /// count against the limits for those element kinds). In that case, we
488
        /// strictly follow the max-constraints, and can fail to satisfy this
489
        /// minimum number.
490
        ///
491
        /// [^1]: the maximum number of functions is also limited by the number
492
        /// of function types arbitrarily chosen; strictly speaking, then, the
493
        /// maximum number of imports that can be created due to max-constraints
494
        /// is `sum(min(num_func_types, max_funcs), max_tables, max_globals,
495
        /// max_memories)`.
496
        pub min_imports: usize = 0,
497
498
        /// The minimum number of memories to use. Defaults to 0.
499
        ///
500
        /// This includes imported memories.
501
        pub min_memories: u32 = 0,
502
503
        /// The minimum number of tables to use. Defaults to 0.
504
        ///
505
        /// This includes imported tables.
506
        pub min_tables: u32 = 0,
507
508
        /// The minimum number of tags to generate. Defaults to 0.
509
        pub min_tags: usize = 0,
510
511
        /// The minimum number of types to generate. Defaults to 0.
512
        pub min_types: usize = 0,
513
514
        /// The minimum size, in bytes, of all leb-encoded integers. Defaults to
515
        /// 1.
516
        ///
517
        /// This is useful for ensuring that all leb-encoded integers are
518
        /// decoded as such rather than as simply one byte. This will forcibly
519
        /// extend leb integers with an over-long encoding in some locations if
520
        /// the size would otherwise be smaller than number returned here.
521
        pub min_uleb_size: u8 = 1,
522
523
        /// Determines whether the multi-value results are enabled.
524
        ///
525
        /// Defaults to `true`.
526
        pub multi_value_enabled: bool = true,
527
528
        /// Determines whether the reference types proposal is enabled for
529
        /// generating instructions.
530
        ///
531
        /// Defaults to `false`.
532
        pub reference_types_enabled: bool = false,
533
534
        /// Determines whether the Relaxed SIMD proposal is enabled for
535
        /// generating instructions.
536
        ///
537
        /// Defaults to `false`.
538
        pub relaxed_simd_enabled: bool = false,
539
540
        /// Determines whether the nontrapping-float-to-int-conversions propsal
541
        /// is enabled.
542
        ///
543
        /// Defaults to `true`.
544
        pub saturating_float_to_int_enabled: bool = true,
545
546
        /// Determines whether the sign-extension-ops propsal is enabled.
547
        ///
548
        /// Defaults to `true`.
549
        pub sign_extension_ops_enabled: bool = true,
550
551
        /// Determines whether the SIMD proposal is enabled for generating
552
        /// instructions.
553
        ///
554
        /// Defaults to `false`.
555
        pub simd_enabled: bool = false,
556
557
        /// Determines whether the tail calls proposal is enabled for generating
558
        /// instructions.
559
        ///
560
        /// Defaults to `false`.
561
        pub tail_call_enabled: bool = false,
562
563
        /// Whether every Wasm table must have a maximum size
564
        /// specified. Defaults to `false`.
565
        pub table_max_size_required: bool = false,
566
567
        /// Determines whether the threads proposal is enabled.
568
        ///
569
        /// The [threads proposal] involves shared linear memory, new atomic
570
        /// instructions, and new `wait` and `notify` instructions.
571
        ///
572
        /// [threads proposal]: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md
573
        ///
574
        /// Defaults to `false`.
575
        pub threads_enabled: bool = false,
576
577
        /// Indicates whether wasm-smith is allowed to generate invalid function
578
        /// bodies.
579
        ///
580
        /// When enabled this option will enable taking raw bytes from the input
581
        /// byte stream and using them as a wasm function body. This means that
582
        /// the output module is not guaranteed to be valid but can help tickle
583
        /// various parts of validation/compilation in some circumstances as
584
        /// well.
585
        ///
586
        /// Defaults to `false`.
587
        pub allow_invalid_funcs: bool = false,
588
    }
589
}
590
591
/// This is a tuple `(a, b, c)` where
592
///
593
/// * `a / (a+b+c)` is the probability of generating a memory offset within
594
///   `0..memory.min_size`, i.e. an offset that is definitely in bounds of a
595
///   non-empty memory. (Note that if a memory is zero-sized, however, no offset
596
///   will ever be in bounds.)
597
///
598
/// * `b / (a+b+c)` is the probability of generating a memory offset within
599
///   `memory.min_size..memory.max_size`, i.e. an offset that is possibly in
600
///   bounds if the memory has been grown.
601
///
602
/// * `c / (a+b+c)` is the probability of generating a memory offset within the
603
///   range `memory.max_size..`, i.e. an offset that is definitely out of
604
///   bounds.
605
///
606
/// At least one of `a`, `b`, and `c` must be non-zero.
607
///
608
/// If you want to always generate memory offsets that are definitely in bounds
609
/// of a non-zero-sized memory, for example, you could return `(1, 0, 0)`.
610
///
611
/// The default is `(90, 9, 1)`.
612
#[derive(Clone, Debug)]
613
#[cfg_attr(feature = "serde_derive", derive(serde_derive::Deserialize))]
614
pub struct MemoryOffsetChoices(pub u32, pub u32, pub u32);
615
616
impl Default for MemoryOffsetChoices {
617
5.67k
    fn default() -> Self {
618
5.67k
        MemoryOffsetChoices(90, 9, 1)
619
5.67k
    }
620
}
621
622
#[cfg(feature = "_internal_cli")]
623
impl std::str::FromStr for MemoryOffsetChoices {
624
    type Err = String;
625
    fn from_str(s: &str) -> Result<Self, Self::Err> {
626
        use std::str::FromStr;
627
        let mut parts = s.split(",");
628
        let a = parts
629
            .next()
630
            .ok_or_else(|| "need 3 comma separated values".to_string())?;
631
        let a = <u32 as FromStr>::from_str(a).map_err(|e| e.to_string())?;
632
        let b = parts
633
            .next()
634
            .ok_or_else(|| "need 3 comma separated values".to_string())?;
635
        let b = <u32 as FromStr>::from_str(b).map_err(|e| e.to_string())?;
636
        let c = parts
637
            .next()
638
            .ok_or_else(|| "need 3 comma separated values".to_string())?;
639
        let c = <u32 as FromStr>::from_str(c).map_err(|e| e.to_string())?;
640
        if parts.next().is_some() {
641
            return Err("found more than 3 comma separated values".to_string());
642
        }
643
        Ok(MemoryOffsetChoices(a, b, c))
644
    }
645
}
646
647
impl<'a> Arbitrary<'a> for Config {
648
0
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
649
        const MAX_MAXIMUM: usize = 1000;
650
651
0
        let reference_types_enabled: bool = u.arbitrary()?;
652
0
        let max_tables = if reference_types_enabled { 100 } else { 1 };
653
654
        Ok(Config {
655
0
            max_types: u.int_in_range(0..=MAX_MAXIMUM)?,
656
0
            max_imports: u.int_in_range(0..=MAX_MAXIMUM)?,
657
0
            max_tags: u.int_in_range(0..=MAX_MAXIMUM)?,
658
0
            max_funcs: u.int_in_range(0..=MAX_MAXIMUM)?,
659
0
            max_globals: u.int_in_range(0..=MAX_MAXIMUM)?,
660
0
            max_exports: u.int_in_range(0..=MAX_MAXIMUM)?,
661
0
            max_element_segments: u.int_in_range(0..=MAX_MAXIMUM)?,
662
0
            max_elements: u.int_in_range(0..=MAX_MAXIMUM)?,
663
0
            max_data_segments: u.int_in_range(0..=MAX_MAXIMUM)?,
664
0
            max_instructions: u.int_in_range(0..=MAX_MAXIMUM)?,
665
0
            max_memories: u.int_in_range(0..=100)?,
666
0
            max_tables,
667
0
            max_memory32_pages: u.int_in_range(0..=1 << 16)?,
668
0
            max_memory64_pages: u.int_in_range(0..=1 << 48)?,
669
0
            min_uleb_size: u.int_in_range(0..=5)?,
670
0
            bulk_memory_enabled: u.arbitrary()?,
671
0
            reference_types_enabled,
672
0
            simd_enabled: u.arbitrary()?,
673
0
            multi_value_enabled: u.arbitrary()?,
674
0
            max_aliases: u.int_in_range(0..=MAX_MAXIMUM)?,
675
0
            max_nesting_depth: u.int_in_range(0..=10)?,
676
0
            saturating_float_to_int_enabled: u.arbitrary()?,
677
0
            sign_extension_ops_enabled: u.arbitrary()?,
678
            allowed_instructions: {
679
                use flagset::Flags;
680
0
                let mut allowed = Vec::new();
681
0
                for kind in crate::core::InstructionKind::LIST {
682
0
                    if u.arbitrary()? {
683
0
                        allowed.push(*kind);
684
0
                    }
685
                }
686
0
                InstructionKinds::new(&allowed)
687
0
            },
688
0
            table_max_size_required: u.arbitrary()?,
689
0
            max_table_elements: u.int_in_range(0..=1_000_000)?,
690
0
            disallow_traps: u.arbitrary()?,
691
692
            // These fields, unlike the ones above, are less useful to set.
693
            // They either make weird inputs or are for features not widely
694
            // implemented yet so they're turned off by default.
695
            min_types: 0,
696
            min_imports: 0,
697
            min_tags: 0,
698
            min_funcs: 0,
699
            min_globals: 0,
700
            min_exports: 0,
701
            min_element_segments: 0,
702
            min_elements: 0,
703
            min_data_segments: 0,
704
            min_memories: 0,
705
            min_tables: 0,
706
            memory_max_size_required: false,
707
            max_instances: 0,
708
            max_modules: 0,
709
            max_components: 0,
710
            max_values: 0,
711
0
            memory_offset_choices: MemoryOffsetChoices::default(),
712
0
            allow_start_export: true,
713
0
            relaxed_simd_enabled: false,
714
0
            exceptions_enabled: false,
715
0
            memory64_enabled: false,
716
0
            max_type_size: 1000,
717
0
            canonicalize_nans: false,
718
0
            available_imports: None,
719
0
            exports: None,
720
            threads_enabled: false,
721
            export_everything: false,
722
            tail_call_enabled: false,
723
            gc_enabled: false,
724
            custom_page_sizes_enabled: false,
725
            generate_custom_sections: false,
726
            allow_invalid_funcs: false,
727
        })
728
0
    }
729
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/core.rs
Line
Count
Source (jump to first uncovered line)
1
//! Generating arbitary core Wasm modules.
2
3
mod code_builder;
4
pub(crate) mod encode;
5
mod terminate;
6
7
use crate::{arbitrary_loop, limited_string, unique_string, Config};
8
use arbitrary::{Arbitrary, Result, Unstructured};
9
use code_builder::CodeBuilderAllocations;
10
use flagset::{flags, FlagSet};
11
use std::collections::{HashMap, HashSet};
12
use std::fmt;
13
use std::mem;
14
use std::ops::Range;
15
use std::rc::Rc;
16
use std::str::{self, FromStr};
17
use wasm_encoder::{
18
    ArrayType, BlockType, ConstExpr, ExportKind, FieldType, HeapType, RefType, StorageType,
19
    StructType, ValType,
20
};
21
pub(crate) use wasm_encoder::{GlobalType, MemoryType, TableType};
22
23
// NB: these constants are used to control the rate at which various events
24
// occur. For more information see where these constants are used. Their values
25
// are somewhat random in the sense that they're not scientifically determined
26
// or anything like that, I just threw a bunch of random data at wasm-smith and
27
// measured various rates of ooms/traps/etc and adjusted these so abnormal
28
// events were ~1% of the time.
29
const CHANCE_OFFSET_INBOUNDS: usize = 10; // bigger = less traps
30
const CHANCE_SEGMENT_ON_EMPTY: usize = 10; // bigger = less traps
31
const PCT_INBOUNDS: f64 = 0.995; // bigger = less traps
32
33
type Instruction = wasm_encoder::Instruction<'static>;
34
35
/// A pseudo-random WebAssembly module.
36
///
37
/// Construct instances of this type (with default configuration) with [the
38
/// `Arbitrary`
39
/// trait](https://docs.rs/arbitrary/*/arbitrary/trait.Arbitrary.html).
40
///
41
/// ## Configuring Generated Modules
42
///
43
/// To configure the shape of generated module, create a
44
/// [`Config`][crate::Config] and then call [`Module::new`][crate::Module::new]
45
/// with it.
46
pub struct Module {
47
    config: Config,
48
    duplicate_imports_behavior: DuplicateImportsBehavior,
49
    valtypes: Vec<ValType>,
50
51
    /// All types locally defined in this module (available in the type index
52
    /// space).
53
    types: Vec<SubType>,
54
55
    /// Non-overlapping ranges within `types` that belong to the same rec
56
    /// group. All of `types` is covered by these ranges. When GC is not
57
    /// enabled, these are all single-element ranges.
58
    rec_groups: Vec<Range<usize>>,
59
60
    /// A map from a super type to all of its sub types.
61
    super_to_sub_types: HashMap<u32, Vec<u32>>,
62
63
    /// Indices within `types` that are not final types.
64
    can_subtype: Vec<u32>,
65
66
    /// Whether we should encode a types section, even if `self.types` is empty.
67
    should_encode_types: bool,
68
69
    /// All of this module's imports. These don't have their own index space,
70
    /// but instead introduce entries to each imported entity's associated index
71
    /// space.
72
    imports: Vec<Import>,
73
74
    /// Whether we should encode an imports section, even if `self.imports` is
75
    /// empty.
76
    should_encode_imports: bool,
77
78
    /// Indices within `types` that are array types.
79
    array_types: Vec<u32>,
80
81
    /// Indices within `types` that are function types.
82
    func_types: Vec<u32>,
83
84
    /// Indices within `types that are struct types.
85
    struct_types: Vec<u32>,
86
87
    /// Number of imported items into this module.
88
    num_imports: usize,
89
90
    /// The number of tags defined in this module (not imported or
91
    /// aliased).
92
    num_defined_tags: usize,
93
94
    /// The number of functions defined in this module (not imported or
95
    /// aliased).
96
    num_defined_funcs: usize,
97
98
    /// Initialization expressions for all defined tables in this module.
99
    defined_tables: Vec<Option<ConstExpr>>,
100
101
    /// The number of memories defined in this module (not imported or
102
    /// aliased).
103
    num_defined_memories: usize,
104
105
    /// The indexes and initialization expressions of globals defined in this
106
    /// module.
107
    defined_globals: Vec<(u32, ConstExpr)>,
108
109
    /// All tags available to this module, sorted by their index. The list
110
    /// entry is the type of each tag.
111
    tags: Vec<TagType>,
112
113
    /// All functions available to this module, sorted by their index. The list
114
    /// entry points to the index in this module where the function type is
115
    /// defined (if available) and provides the type of the function.
116
    funcs: Vec<(u32, Rc<FuncType>)>,
117
118
    /// All tables available to this module, sorted by their index. The list
119
    /// entry is the type of each table.
120
    tables: Vec<TableType>,
121
122
    /// All globals available to this module, sorted by their index. The list
123
    /// entry is the type of each global.
124
    globals: Vec<GlobalType>,
125
126
    /// All memories available to this module, sorted by their index. The list
127
    /// entry is the type of each memory.
128
    memories: Vec<MemoryType>,
129
130
    exports: Vec<(String, ExportKind, u32)>,
131
    start: Option<u32>,
132
    elems: Vec<ElementSegment>,
133
    code: Vec<Code>,
134
    data: Vec<DataSegment>,
135
136
    /// The predicted size of the effective type of this module, based on this
137
    /// module's size of the types of imports/exports.
138
    type_size: u32,
139
140
    /// Names currently exported from this module.
141
    export_names: HashSet<String>,
142
143
    /// Reusable buffer in `self.arbitrary_const_expr` to amortize the cost of
144
    /// allocation.
145
    const_expr_choices: Vec<Box<dyn Fn(&mut Unstructured, ValType) -> Result<ConstExpr>>>,
146
147
    /// What the maximum type index that can be referenced is.
148
    max_type_limit: MaxTypeLimit,
149
150
    /// Some known-interesting values, such as powers of two, values just before
151
    /// or just after a memory size, etc...
152
    interesting_values32: Vec<u32>,
153
    interesting_values64: Vec<u64>,
154
}
155
156
impl<'a> Arbitrary<'a> for Module {
157
5.67k
    fn arbitrary(u: &mut Unstructured<'a>) -> Result<Self> {
158
5.67k
        Module::new(Config::default(), u)
159
5.67k
    }
160
}
161
162
impl fmt::Debug for Module {
163
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
164
0
        f.debug_struct("Module")
165
0
            .field("config", &self.config)
166
0
            .field(&"...", &"...")
167
0
            .finish()
168
0
    }
169
}
170
171
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
172
pub(crate) enum DuplicateImportsBehavior {
173
    Allowed,
174
    Disallowed,
175
}
176
177
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
178
enum MaxTypeLimit {
179
    ModuleTypes,
180
    Num(u32),
181
}
182
183
impl Module {
184
    /// Returns a reference to the internal configuration.
185
3.07k
    pub fn config(&self) -> &Config {
186
3.07k
        &self.config
187
3.07k
    }
188
189
    /// Creates a new `Module` with the specified `config` for
190
    /// configuration and `Unstructured` for the DNA of this module.
191
5.67k
    pub fn new(config: Config, u: &mut Unstructured<'_>) -> Result<Self> {
192
5.67k
        Self::new_internal(config, u, DuplicateImportsBehavior::Allowed)
193
5.67k
    }
194
195
5.67k
    pub(crate) fn new_internal(
196
5.67k
        config: Config,
197
5.67k
        u: &mut Unstructured<'_>,
198
5.67k
        duplicate_imports_behavior: DuplicateImportsBehavior,
199
5.67k
    ) -> Result<Self> {
200
5.67k
        let mut module = Module::empty(config, duplicate_imports_behavior);
201
5.67k
        module.build(u)?;
202
5.67k
        Ok(module)
203
5.67k
    }
204
205
5.67k
    fn empty(config: Config, duplicate_imports_behavior: DuplicateImportsBehavior) -> Self {
206
5.67k
        Module {
207
5.67k
            config,
208
5.67k
            duplicate_imports_behavior,
209
5.67k
            valtypes: Vec::new(),
210
5.67k
            types: Vec::new(),
211
5.67k
            rec_groups: Vec::new(),
212
5.67k
            can_subtype: Vec::new(),
213
5.67k
            super_to_sub_types: HashMap::new(),
214
5.67k
            should_encode_types: false,
215
5.67k
            imports: Vec::new(),
216
5.67k
            should_encode_imports: false,
217
5.67k
            array_types: Vec::new(),
218
5.67k
            func_types: Vec::new(),
219
5.67k
            struct_types: Vec::new(),
220
5.67k
            num_imports: 0,
221
5.67k
            num_defined_tags: 0,
222
5.67k
            num_defined_funcs: 0,
223
5.67k
            defined_tables: Vec::new(),
224
5.67k
            num_defined_memories: 0,
225
5.67k
            defined_globals: Vec::new(),
226
5.67k
            tags: Vec::new(),
227
5.67k
            funcs: Vec::new(),
228
5.67k
            tables: Vec::new(),
229
5.67k
            globals: Vec::new(),
230
5.67k
            memories: Vec::new(),
231
5.67k
            exports: Vec::new(),
232
5.67k
            start: None,
233
5.67k
            elems: Vec::new(),
234
5.67k
            code: Vec::new(),
235
5.67k
            data: Vec::new(),
236
5.67k
            type_size: 0,
237
5.67k
            export_names: HashSet::new(),
238
5.67k
            const_expr_choices: Vec::new(),
239
5.67k
            max_type_limit: MaxTypeLimit::ModuleTypes,
240
5.67k
            interesting_values32: Vec::new(),
241
5.67k
            interesting_values64: Vec::new(),
242
5.67k
        }
243
5.67k
    }
244
}
245
246
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
247
pub(crate) struct SubType {
248
    pub(crate) is_final: bool,
249
    pub(crate) supertype: Option<u32>,
250
    pub(crate) composite_type: CompositeType,
251
}
252
253
impl SubType {
254
0
    fn unwrap_struct(&self) -> &StructType {
255
0
        self.composite_type.unwrap_struct()
256
0
    }
257
258
0
    fn unwrap_func(&self) -> &Rc<FuncType> {
259
0
        self.composite_type.unwrap_func()
260
0
    }
261
262
0
    fn unwrap_array(&self) -> &ArrayType {
263
0
        self.composite_type.unwrap_array()
264
0
    }
265
}
266
267
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
268
pub(crate) enum CompositeType {
269
    Array(ArrayType),
270
    Func(Rc<FuncType>),
271
    Struct(StructType),
272
}
273
274
impl CompositeType {
275
0
    fn unwrap_struct(&self) -> &StructType {
276
0
        match self {
277
0
            CompositeType::Struct(s) => s,
278
0
            _ => panic!("not a struct"),
279
        }
280
0
    }
281
282
0
    fn unwrap_func(&self) -> &Rc<FuncType> {
283
0
        match self {
284
0
            CompositeType::Func(f) => f,
285
0
            _ => panic!("not a func"),
286
        }
287
0
    }
288
289
0
    fn unwrap_array(&self) -> &ArrayType {
290
0
        match self {
291
0
            CompositeType::Array(a) => a,
292
0
            _ => panic!("not an array"),
293
        }
294
0
    }
295
}
296
297
/// A function signature.
298
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
299
pub(crate) struct FuncType {
300
    /// Types of the parameter values.
301
    pub(crate) params: Vec<ValType>,
302
    /// Types of the result values.
303
    pub(crate) results: Vec<ValType>,
304
}
305
306
/// An import of an entity provided externally or by a component.
307
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
308
pub(crate) struct Import {
309
    /// The name of the module providing this entity.
310
    pub(crate) module: String,
311
    /// The name of the entity.
312
    pub(crate) field: String,
313
    /// The type of this entity.
314
    pub(crate) entity_type: EntityType,
315
}
316
317
/// Type of an entity.
318
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
319
pub(crate) enum EntityType {
320
    /// A global entity.
321
    Global(GlobalType),
322
    /// A table entity.
323
    Table(TableType),
324
    /// A memory entity.
325
    Memory(MemoryType),
326
    /// A tag entity.
327
    Tag(TagType),
328
    /// A function entity.
329
    Func(u32, Rc<FuncType>),
330
}
331
332
/// Type of a tag.
333
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
334
pub(crate) struct TagType {
335
    /// Index of the function type.
336
    func_type_idx: u32,
337
    /// Type of the function.
338
    func_type: Rc<FuncType>,
339
}
340
341
#[derive(Debug)]
342
struct ElementSegment {
343
    kind: ElementKind,
344
    ty: RefType,
345
    items: Elements,
346
}
347
348
#[derive(Debug)]
349
enum ElementKind {
350
    Passive,
351
    Declared,
352
    Active {
353
        table: Option<u32>, // None == table 0 implicitly
354
        offset: Offset,
355
    },
356
}
357
358
#[derive(Debug)]
359
enum Elements {
360
    Functions(Vec<u32>),
361
    Expressions(Vec<ConstExpr>),
362
}
363
364
#[derive(Debug)]
365
struct Code {
366
    locals: Vec<ValType>,
367
    instructions: Instructions,
368
}
369
370
#[derive(Debug)]
371
enum Instructions {
372
    Generated(Vec<Instruction>),
373
    Arbitrary(Vec<u8>),
374
}
375
376
#[derive(Debug)]
377
struct DataSegment {
378
    kind: DataSegmentKind,
379
    init: Vec<u8>,
380
}
381
382
#[derive(Debug)]
383
enum DataSegmentKind {
384
    Passive,
385
    Active { memory_index: u32, offset: Offset },
386
}
387
388
#[derive(Debug)]
389
pub(crate) enum Offset {
390
    Const32(i32),
391
    Const64(i64),
392
    Global(u32),
393
}
394
395
impl Module {
396
5.67k
    fn build(&mut self, u: &mut Unstructured) -> Result<()> {
397
5.67k
        self.valtypes = configured_valtypes(&self.config);
398
5.67k
399
5.67k
        // We attempt to figure out our available imports *before* creating the types section here,
400
5.67k
        // because the types for the imports are already well-known (specified by the user) and we
401
5.67k
        // must have those populated for all function/etc. imports, no matter what.
402
5.67k
        //
403
5.67k
        // This can affect the available capacity for types and such.
404
5.67k
        if self.arbitrary_imports_from_available(u)? {
405
0
            self.arbitrary_types(u)?;
406
        } else {
407
5.67k
            self.arbitrary_types(u)?;
408
5.67k
            self.arbitrary_imports(u)?;
409
        }
410
411
5.67k
        self.should_encode_imports = !self.imports.is_empty() || u.arbitrary()?;
412
413
5.67k
        self.arbitrary_tags(u)?;
414
5.67k
        self.arbitrary_funcs(u)?;
415
5.67k
        self.arbitrary_tables(u)?;
416
5.67k
        self.arbitrary_memories(u)?;
417
5.67k
        self.arbitrary_globals(u)?;
418
5.67k
        if !self.required_exports(u)? {
419
5.67k
            self.arbitrary_exports(u)?;
420
0
        };
421
5.67k
        self.should_encode_types = !self.types.is_empty() || u.arbitrary()?;
422
5.67k
        self.arbitrary_start(u)?;
423
5.67k
        self.arbitrary_elems(u)?;
424
5.67k
        self.arbitrary_data(u)?;
425
5.67k
        self.arbitrary_code(u)?;
426
5.67k
        Ok(())
427
5.67k
    }
428
429
    #[inline]
430
7.77M
    fn val_type_is_sub_type(&self, a: ValType, b: ValType) -> bool {
431
7.77M
        match (a, b) {
432
7.77M
            (a, b) if a == b => true,
433
0
            (ValType::Ref(a), ValType::Ref(b)) => self.ref_type_is_sub_type(a, b),
434
5.47M
            _ => false,
435
        }
436
7.77M
    }
437
438
    /// Is `a` a subtype of `b`?
439
1.58k
    fn ref_type_is_sub_type(&self, a: RefType, b: RefType) -> bool {
440
1.58k
        if a == b {
441
1.58k
            return true;
442
0
        }
443
0
444
0
        if a.nullable && !b.nullable {
445
0
            return false;
446
0
        }
447
0
448
0
        self.heap_type_is_sub_type(a.heap_type, b.heap_type)
449
1.58k
    }
450
451
0
    fn heap_type_is_sub_type(&self, a: HeapType, b: HeapType) -> bool {
452
0
        use HeapType as HT;
453
0
        match (a, b) {
454
0
            (a, b) if a == b => true,
455
456
0
            (HT::Eq | HT::I31 | HT::Struct | HT::Array | HT::None, HT::Any) => true,
457
0
            (HT::I31 | HT::Struct | HT::Array | HT::None, HT::Eq) => true,
458
0
            (HT::NoExtern, HT::Extern) => true,
459
0
            (HT::NoFunc, HT::Func) => true,
460
0
            (HT::None, HT::I31 | HT::Array | HT::Struct) => true,
461
462
0
            (HT::Concrete(a), HT::Eq | HT::Any) => matches!(
463
0
                self.ty(a).composite_type,
464
                CompositeType::Array(_) | CompositeType::Struct(_)
465
            ),
466
467
0
            (HT::Concrete(a), HT::Struct) => {
468
0
                matches!(self.ty(a).composite_type, CompositeType::Struct(_))
469
            }
470
471
0
            (HT::Concrete(a), HT::Array) => {
472
0
                matches!(self.ty(a).composite_type, CompositeType::Array(_))
473
            }
474
475
0
            (HT::Concrete(a), HT::Func) => {
476
0
                matches!(self.ty(a).composite_type, CompositeType::Func(_))
477
            }
478
479
0
            (HT::Concrete(mut a), HT::Concrete(b)) => loop {
480
0
                if a == b {
481
0
                    return true;
482
0
                }
483
0
                if let Some(supertype) = self.ty(a).supertype {
484
0
                    a = supertype;
485
0
                } else {
486
0
                    return false;
487
                }
488
            },
489
490
0
            (HT::None, HT::Concrete(b)) => matches!(
491
0
                self.ty(b).composite_type,
492
                CompositeType::Array(_) | CompositeType::Struct(_)
493
            ),
494
495
0
            (HT::NoFunc, HT::Concrete(b)) => {
496
0
                matches!(self.ty(b).composite_type, CompositeType::Func(_))
497
            }
498
499
0
            (HT::NoExn, HT::Exn) => true,
500
501
            // Nothing else matches. (Avoid full wildcard matches so that
502
            // adding/modifying variants is easier in the future.)
503
            (HT::Concrete(_), _)
504
            | (HT::Func, _)
505
            | (HT::Extern, _)
506
            | (HT::Any, _)
507
            | (HT::None, _)
508
            | (HT::NoExtern, _)
509
            | (HT::NoFunc, _)
510
            | (HT::Eq, _)
511
            | (HT::Struct, _)
512
            | (HT::Array, _)
513
            | (HT::I31, _)
514
            | (HT::Exn, _)
515
0
            | (HT::NoExn, _) => false,
516
        }
517
0
    }
518
519
5.67k
    fn arbitrary_types(&mut self, u: &mut Unstructured) -> Result<()> {
520
5.67k
        assert!(self.config.min_types <= self.config.max_types);
521
5.67k
        while self.types.len() < self.config.min_types {
522
0
            self.arbitrary_rec_group(u)?;
523
        }
524
11.3k
        while self.types.len() < self.config.max_types {
525
11.3k
            let keep_going = u.arbitrary().unwrap_or(false);
526
11.3k
            if !keep_going {
527
5.67k
                break;
528
5.68k
            }
529
5.68k
            self.arbitrary_rec_group(u)?;
530
        }
531
5.67k
        Ok(())
532
5.67k
    }
533
534
5.68k
    fn add_type(&mut self, ty: SubType) -> u32 {
535
5.68k
        let index = u32::try_from(self.types.len()).unwrap();
536
537
5.68k
        if let Some(supertype) = ty.supertype {
538
0
            self.super_to_sub_types
539
0
                .entry(supertype)
540
0
                .or_default()
541
0
                .push(index);
542
5.68k
        }
543
544
5.68k
        let list = match &ty.composite_type {
545
0
            CompositeType::Array(_) => &mut self.array_types,
546
5.68k
            CompositeType::Func(_) => &mut self.func_types,
547
0
            CompositeType::Struct(_) => &mut self.struct_types,
548
        };
549
5.68k
        list.push(index);
550
5.68k
551
5.68k
        if !ty.is_final {
552
0
            self.can_subtype.push(index);
553
5.68k
        }
554
555
5.68k
        self.types.push(ty);
556
5.68k
        index
557
5.68k
    }
558
559
5.68k
    fn arbitrary_rec_group(&mut self, u: &mut Unstructured) -> Result<()> {
560
5.68k
        let rec_group_start = self.types.len();
561
5.68k
562
5.68k
        assert!(matches!(self.max_type_limit, MaxTypeLimit::ModuleTypes));
563
564
5.68k
        if self.config.gc_enabled {
565
            // With small probability, clone an existing rec group.
566
0
            if self.clonable_rec_groups().next().is_some() && u.ratio(1, u8::MAX)? {
567
0
                return self.clone_rec_group(u);
568
0
            }
569
0
570
0
            // Otherwise, create a new rec group with multiple types inside.
571
0
            let max_rec_group_size = self.config.max_types - self.types.len();
572
0
            let rec_group_size = u.int_in_range(0..=max_rec_group_size)?;
573
0
            let type_ref_limit = u32::try_from(self.types.len() + rec_group_size).unwrap();
574
0
            self.max_type_limit = MaxTypeLimit::Num(type_ref_limit);
575
0
            for _ in 0..rec_group_size {
576
0
                let ty = self.arbitrary_sub_type(u)?;
577
0
                self.add_type(ty);
578
            }
579
        } else {
580
5.68k
            let type_ref_limit = u32::try_from(self.types.len()).unwrap();
581
5.68k
            self.max_type_limit = MaxTypeLimit::Num(type_ref_limit);
582
5.68k
            let ty = self.arbitrary_sub_type(u)?;
583
5.68k
            self.add_type(ty);
584
        }
585
586
5.68k
        self.max_type_limit = MaxTypeLimit::ModuleTypes;
587
5.68k
588
5.68k
        self.rec_groups.push(rec_group_start..self.types.len());
589
5.68k
        Ok(())
590
5.68k
    }
591
592
    /// Returns an iterator of rec groups that we could currently clone while
593
    /// still staying within the max types limit.
594
0
    fn clonable_rec_groups(&self) -> impl Iterator<Item = Range<usize>> + '_ {
595
0
        self.rec_groups
596
0
            .iter()
597
0
            .filter(|r| r.end - r.start <= self.config.max_types.saturating_sub(self.types.len()))
598
0
            .cloned()
599
0
    }
600
601
0
    fn clone_rec_group(&mut self, u: &mut Unstructured) -> Result<()> {
602
0
        // NB: this does *not* guarantee that the cloned rec group will
603
0
        // canonicalize the same as the original rec group and be
604
0
        // deduplicated. That would reqiure a second pass over the cloned types
605
0
        // to rewrite references within the original rec group to be references
606
0
        // into the new rec group. That might make sense to do one day, but for
607
0
        // now we don't do it. That also means that we can't mark the new types
608
0
        // as "subtypes" of the old types and vice versa.
609
0
        let candidates: Vec<_> = self.clonable_rec_groups().collect();
610
0
        let group = u.choose(&candidates)?.clone();
611
0
        let new_rec_group_start = self.types.len();
612
0
        for index in group {
613
0
            let orig_ty_index = u32::try_from(index).unwrap();
614
0
            let ty = self.ty(orig_ty_index).clone();
615
0
            self.add_type(ty);
616
0
        }
617
0
        self.rec_groups.push(new_rec_group_start..self.types.len());
618
0
        Ok(())
619
0
    }
620
621
5.68k
    fn arbitrary_sub_type(&mut self, u: &mut Unstructured) -> Result<SubType> {
622
5.68k
        if !self.config.gc_enabled {
623
            return Ok(SubType {
624
                is_final: true,
625
5.68k
                supertype: None,
626
5.68k
                composite_type: CompositeType::Func(self.arbitrary_func_type(u)?),
627
            });
628
0
        }
629
0
630
0
        if !self.can_subtype.is_empty() && u.ratio(1, 32_u8)? {
631
0
            self.arbitrary_sub_type_of_super_type(u)
632
        } else {
633
            Ok(SubType {
634
0
                is_final: u.arbitrary()?,
635
0
                supertype: None,
636
0
                composite_type: self.arbitrary_composite_type(u)?,
637
            })
638
        }
639
5.68k
    }
640
641
0
    fn arbitrary_sub_type_of_super_type(&mut self, u: &mut Unstructured) -> Result<SubType> {
642
0
        let supertype = *u.choose(&self.can_subtype)?;
643
0
        let mut composite_type = self.types[usize::try_from(supertype).unwrap()]
644
0
            .composite_type
645
0
            .clone();
646
0
        match &mut composite_type {
647
0
            CompositeType::Array(a) => {
648
0
                a.0 = self.arbitrary_matching_field_type(u, a.0)?;
649
            }
650
0
            CompositeType::Func(f) => {
651
0
                *f = self.arbitrary_matching_func_type(u, f)?;
652
            }
653
0
            CompositeType::Struct(s) => {
654
0
                *s = self.arbitrary_matching_struct_type(u, s)?;
655
            }
656
        }
657
        Ok(SubType {
658
0
            is_final: u.arbitrary()?,
659
0
            supertype: Some(supertype),
660
0
            composite_type,
661
        })
662
0
    }
663
664
0
    fn arbitrary_matching_struct_type(
665
0
        &mut self,
666
0
        u: &mut Unstructured,
667
0
        ty: &StructType,
668
0
    ) -> Result<StructType> {
669
0
        let len_extra_fields = u.int_in_range(0..=5)?;
670
0
        let mut fields = Vec::with_capacity(ty.fields.len() + len_extra_fields);
671
0
        for field in ty.fields.iter() {
672
0
            fields.push(self.arbitrary_matching_field_type(u, *field)?);
673
        }
674
0
        for _ in 0..len_extra_fields {
675
0
            fields.push(self.arbitrary_field_type(u)?);
676
        }
677
0
        Ok(StructType {
678
0
            fields: fields.into_boxed_slice(),
679
0
        })
680
0
    }
681
682
0
    fn arbitrary_matching_field_type(
683
0
        &mut self,
684
0
        u: &mut Unstructured,
685
0
        ty: FieldType,
686
0
    ) -> Result<FieldType> {
687
0
        Ok(FieldType {
688
0
            element_type: self.arbitrary_matching_storage_type(u, ty.element_type)?,
689
0
            mutable: if ty.mutable { u.arbitrary()? } else { false },
690
        })
691
0
    }
692
693
0
    fn arbitrary_matching_storage_type(
694
0
        &mut self,
695
0
        u: &mut Unstructured,
696
0
        ty: StorageType,
697
0
    ) -> Result<StorageType> {
698
0
        match ty {
699
0
            StorageType::I8 => Ok(StorageType::I8),
700
0
            StorageType::I16 => Ok(StorageType::I16),
701
0
            StorageType::Val(ty) => Ok(StorageType::Val(self.arbitrary_matching_val_type(u, ty)?)),
702
        }
703
0
    }
704
705
2.50k
    fn arbitrary_matching_val_type(
706
2.50k
        &mut self,
707
2.50k
        u: &mut Unstructured,
708
2.50k
        ty: ValType,
709
2.50k
    ) -> Result<ValType> {
710
2.50k
        match ty {
711
1.67k
            ValType::I32 => Ok(ValType::I32),
712
323
            ValType::I64 => Ok(ValType::I64),
713
322
            ValType::F32 => Ok(ValType::F32),
714
184
            ValType::F64 => Ok(ValType::F64),
715
0
            ValType::V128 => Ok(ValType::V128),
716
0
            ValType::Ref(ty) => Ok(ValType::Ref(self.arbitrary_matching_ref_type(u, ty)?)),
717
        }
718
2.50k
    }
719
720
1.58k
    fn arbitrary_matching_ref_type(&self, u: &mut Unstructured, ty: RefType) -> Result<RefType> {
721
1.58k
        Ok(RefType {
722
1.58k
            nullable: ty.nullable,
723
1.58k
            heap_type: self.arbitrary_matching_heap_type(u, ty.heap_type)?,
724
        })
725
1.58k
    }
726
727
1.58k
    fn arbitrary_matching_heap_type(&self, u: &mut Unstructured, ty: HeapType) -> Result<HeapType> {
728
1.58k
        if !self.config.gc_enabled {
729
1.58k
            return Ok(ty);
730
0
        }
731
0
        use HeapType as HT;
732
0
        let mut choices = vec![ty];
733
0
        match ty {
734
0
            HT::Any => {
735
0
                choices.extend([HT::Eq, HT::Struct, HT::Array, HT::I31, HT::None]);
736
0
                choices.extend(self.array_types.iter().copied().map(HT::Concrete));
737
0
                choices.extend(self.struct_types.iter().copied().map(HT::Concrete));
738
0
            }
739
0
            HT::Eq => {
740
0
                choices.extend([HT::Struct, HT::Array, HT::I31, HT::None]);
741
0
                choices.extend(self.array_types.iter().copied().map(HT::Concrete));
742
0
                choices.extend(self.struct_types.iter().copied().map(HT::Concrete));
743
0
            }
744
0
            HT::Struct => {
745
0
                choices.extend([HT::Struct, HT::None]);
746
0
                choices.extend(self.struct_types.iter().copied().map(HT::Concrete));
747
0
            }
748
0
            HT::Array => {
749
0
                choices.extend([HT::Array, HT::None]);
750
0
                choices.extend(self.array_types.iter().copied().map(HT::Concrete));
751
0
            }
752
0
            HT::I31 => {
753
0
                choices.push(HT::None);
754
0
            }
755
0
            HT::Concrete(idx) => {
756
0
                if let Some(subs) = self.super_to_sub_types.get(&idx) {
757
0
                    choices.extend(subs.iter().copied().map(HT::Concrete));
758
0
                }
759
0
                match self
760
0
                    .types
761
0
                    .get(usize::try_from(idx).unwrap())
762
0
                    .map(|ty| &ty.composite_type)
763
                {
764
                    Some(CompositeType::Array(_)) | Some(CompositeType::Struct(_)) => {
765
0
                        choices.push(HT::None)
766
                    }
767
0
                    Some(CompositeType::Func(_)) => choices.push(HT::NoFunc),
768
0
                    None => {
769
0
                        // The referenced type might be part of this same rec
770
0
                        // group we are currently generating, but not generated
771
0
                        // yet. In this case, leave `choices` as it is, and we
772
0
                        // will just end up choosing the original type again
773
0
                        // down below, which is fine.
774
0
                    }
775
                }
776
            }
777
0
            HT::Func => {
778
0
                choices.extend(self.func_types.iter().copied().map(HT::Concrete));
779
0
                choices.push(HT::NoFunc);
780
0
            }
781
0
            HT::Extern => {
782
0
                choices.push(HT::NoExtern);
783
0
            }
784
0
            HT::Exn | HT::NoExn | HT::None | HT::NoExtern | HT::NoFunc => {}
785
        }
786
0
        Ok(*u.choose(&choices)?)
787
1.58k
    }
788
789
0
    fn arbitrary_matching_func_type(
790
0
        &mut self,
791
0
        u: &mut Unstructured,
792
0
        ty: &FuncType,
793
0
    ) -> Result<Rc<FuncType>> {
794
0
        // Note: parameters are contravariant, results are covariant. See
795
0
        // https://github.com/bytecodealliance/wasm-tools/blob/0616ef196a183cf137ee06b4a5993b7d590088bf/crates/wasmparser/src/readers/core/types/matches.rs#L137-L174
796
0
        // for details.
797
0
        let mut params = Vec::with_capacity(ty.params.len());
798
0
        for param in &ty.params {
799
0
            params.push(self.arbitrary_super_type_of_val_type(u, *param)?);
800
        }
801
0
        let mut results = Vec::with_capacity(ty.results.len());
802
0
        for result in &ty.results {
803
0
            results.push(self.arbitrary_matching_val_type(u, *result)?);
804
        }
805
0
        Ok(Rc::new(FuncType { params, results }))
806
0
    }
807
808
0
    fn arbitrary_super_type_of_val_type(
809
0
        &mut self,
810
0
        u: &mut Unstructured,
811
0
        ty: ValType,
812
0
    ) -> Result<ValType> {
813
0
        match ty {
814
0
            ValType::I32 => Ok(ValType::I32),
815
0
            ValType::I64 => Ok(ValType::I64),
816
0
            ValType::F32 => Ok(ValType::F32),
817
0
            ValType::F64 => Ok(ValType::F64),
818
0
            ValType::V128 => Ok(ValType::V128),
819
0
            ValType::Ref(ty) => Ok(ValType::Ref(self.arbitrary_super_type_of_ref_type(u, ty)?)),
820
        }
821
0
    }
822
823
0
    fn arbitrary_super_type_of_ref_type(
824
0
        &self,
825
0
        u: &mut Unstructured,
826
0
        ty: RefType,
827
0
    ) -> Result<RefType> {
828
0
        Ok(RefType {
829
0
            // TODO: For now, only create allow nullable reference
830
0
            // types. Eventually we should support non-nullable reference types,
831
0
            // but this means that we will also need to recognize when it is
832
0
            // impossible to create an instance of the reference (eg `(ref
833
0
            // nofunc)` has no instances, and self-referential types that
834
0
            // contain a non-null self-reference are also impossible to create).
835
0
            nullable: true,
836
0
            heap_type: self.arbitrary_super_type_of_heap_type(u, ty.heap_type)?,
837
        })
838
0
    }
839
840
0
    fn arbitrary_super_type_of_heap_type(
841
0
        &self,
842
0
        u: &mut Unstructured,
843
0
        ty: HeapType,
844
0
    ) -> Result<HeapType> {
845
0
        if !self.config.gc_enabled {
846
0
            return Ok(ty);
847
0
        }
848
0
        use HeapType as HT;
849
0
        let mut choices = vec![ty];
850
0
        match ty {
851
0
            HT::None => {
852
0
                choices.extend([HT::Any, HT::Eq, HT::Struct, HT::Array, HT::I31]);
853
0
                choices.extend(self.array_types.iter().copied().map(HT::Concrete));
854
0
                choices.extend(self.struct_types.iter().copied().map(HT::Concrete));
855
0
            }
856
0
            HT::NoExtern => {
857
0
                choices.push(HT::Extern);
858
0
            }
859
0
            HT::NoFunc => {
860
0
                choices.extend(self.func_types.iter().copied().map(HT::Concrete));
861
0
                choices.push(HT::Func);
862
0
            }
863
0
            HT::NoExn => {
864
0
                choices.push(HT::Exn);
865
0
            }
866
0
            HT::Concrete(mut idx) => {
867
0
                match &self
868
0
                    .types
869
0
                    .get(usize::try_from(idx).unwrap())
870
0
                    .map(|ty| &ty.composite_type)
871
                {
872
0
                    Some(CompositeType::Array(_)) => {
873
0
                        choices.extend([HT::Any, HT::Eq, HT::Array]);
874
0
                    }
875
0
                    Some(CompositeType::Func(_)) => {
876
0
                        choices.push(HT::Func);
877
0
                    }
878
0
                    Some(CompositeType::Struct(_)) => {
879
0
                        choices.extend([HT::Any, HT::Eq, HT::Struct]);
880
0
                    }
881
0
                    None => {
882
0
                        // Same as in `arbitrary_matching_heap_type`: this was a
883
0
                        // forward reference to a concrete type that is part of
884
0
                        // this same rec group we are generating right now, and
885
0
                        // therefore we haven't generated that type yet. Just
886
0
                        // leave `choices` as it is and we will choose the
887
0
                        // original type again down below.
888
0
                    }
889
                }
890
0
                while let Some(supertype) = self
891
0
                    .types
892
0
                    .get(usize::try_from(idx).unwrap())
893
0
                    .and_then(|ty| ty.supertype)
894
0
                {
895
0
                    choices.push(HT::Concrete(supertype));
896
0
                    idx = supertype;
897
0
                }
898
            }
899
0
            HT::Struct | HT::Array | HT::I31 => {
900
0
                choices.extend([HT::Any, HT::Eq]);
901
0
            }
902
0
            HT::Eq => {
903
0
                choices.push(HT::Any);
904
0
            }
905
0
            HT::Exn | HT::Any | HT::Func | HT::Extern => {}
906
        }
907
0
        Ok(*u.choose(&choices)?)
908
0
    }
909
910
0
    fn arbitrary_composite_type(&mut self, u: &mut Unstructured) -> Result<CompositeType> {
911
0
        if !self.config.gc_enabled {
912
0
            return Ok(CompositeType::Func(self.arbitrary_func_type(u)?));
913
0
        }
914
0
915
0
        match u.int_in_range(0..=2)? {
916
            0 => Ok(CompositeType::Array(ArrayType(
917
0
                self.arbitrary_field_type(u)?,
918
            ))),
919
0
            1 => Ok(CompositeType::Func(self.arbitrary_func_type(u)?)),
920
0
            2 => Ok(CompositeType::Struct(self.arbitrary_struct_type(u)?)),
921
0
            _ => unreachable!(),
922
        }
923
0
    }
924
925
0
    fn arbitrary_struct_type(&mut self, u: &mut Unstructured) -> Result<StructType> {
926
0
        let len = u.int_in_range(0..=20)?;
927
0
        let mut fields = Vec::with_capacity(len);
928
0
        for _ in 0..len {
929
0
            fields.push(self.arbitrary_field_type(u)?);
930
        }
931
0
        Ok(StructType {
932
0
            fields: fields.into_boxed_slice(),
933
0
        })
934
0
    }
935
936
0
    fn arbitrary_field_type(&mut self, u: &mut Unstructured) -> Result<FieldType> {
937
0
        Ok(FieldType {
938
0
            element_type: self.arbitrary_storage_type(u)?,
939
0
            mutable: u.arbitrary()?,
940
        })
941
0
    }
942
943
0
    fn arbitrary_storage_type(&mut self, u: &mut Unstructured) -> Result<StorageType> {
944
0
        match u.int_in_range(0..=2)? {
945
0
            0 => Ok(StorageType::I8),
946
0
            1 => Ok(StorageType::I16),
947
0
            2 => Ok(StorageType::Val(self.arbitrary_valtype(u)?)),
948
0
            _ => unreachable!(),
949
        }
950
0
    }
951
952
1.32k
    fn arbitrary_ref_type(&self, u: &mut Unstructured) -> Result<RefType> {
953
1.32k
        if !self.config.reference_types_enabled {
954
1.32k
            return Ok(RefType::FUNCREF);
955
0
        }
956
0
        Ok(RefType {
957
0
            nullable: true,
958
0
            heap_type: self.arbitrary_heap_type(u)?,
959
        })
960
1.32k
    }
961
962
0
    fn arbitrary_heap_type(&self, u: &mut Unstructured) -> Result<HeapType> {
963
0
        assert!(self.config.reference_types_enabled);
964
965
0
        let concrete_type_limit = match self.max_type_limit {
966
0
            MaxTypeLimit::Num(n) => n,
967
0
            MaxTypeLimit::ModuleTypes => u32::try_from(self.types.len()).unwrap(),
968
        };
969
970
0
        if self.config.gc_enabled && concrete_type_limit > 0 && u.arbitrary()? {
971
0
            let idx = u.int_in_range(0..=concrete_type_limit - 1)?;
972
0
            return Ok(HeapType::Concrete(idx));
973
0
        }
974
0
975
0
        let mut choices = vec![HeapType::Func, HeapType::Extern];
976
0
        if self.config.exceptions_enabled {
977
0
            choices.push(HeapType::Exn);
978
0
        }
979
0
        if self.config.gc_enabled {
980
0
            choices.extend(
981
0
                [
982
0
                    HeapType::Any,
983
0
                    HeapType::None,
984
0
                    HeapType::NoExtern,
985
0
                    HeapType::NoFunc,
986
0
                    HeapType::Eq,
987
0
                    HeapType::Struct,
988
0
                    HeapType::Array,
989
0
                    HeapType::I31,
990
0
                ]
991
0
                .iter()
992
0
                .copied(),
993
0
            );
994
0
        }
995
0
        u.choose(&choices).copied()
996
0
    }
997
998
5.68k
    fn arbitrary_func_type(&mut self, u: &mut Unstructured) -> Result<Rc<FuncType>> {
999
5.68k
        let mut params = vec![];
1000
5.68k
        let mut results = vec![];
1001
5.68k
        let max_params = 20;
1002
5.68k
        arbitrary_loop(u, 0, max_params, |u| {
1003
2.68k
            params.push(self.arbitrary_valtype(u)?);
1004
2.68k
            Ok(true)
1005
5.68k
        })?;
1006
5.68k
        let max_results = if self.config.multi_value_enabled {
1007
5.68k
            max_params
1008
        } else {
1009
0
            1
1010
        };
1011
5.68k
        arbitrary_loop(u, 0, max_results, |u| {
1012
4.12k
            results.push(self.arbitrary_valtype(u)?);
1013
4.12k
            Ok(true)
1014
5.68k
        })?;
1015
5.68k
        Ok(Rc::new(FuncType { params, results }))
1016
5.68k
    }
1017
1018
4.32k
    fn can_add_local_or_import_tag(&self) -> bool {
1019
4.32k
        self.config.exceptions_enabled
1020
0
            && self.has_tag_func_types()
1021
0
            && self.tags.len() < self.config.max_tags
1022
4.32k
    }
1023
1024
20.1k
    fn can_add_local_or_import_func(&self) -> bool {
1025
20.1k
        !self.func_types.is_empty() && self.funcs.len() < self.config.max_funcs
1026
20.1k
    }
1027
1028
5.38k
    fn can_add_local_or_import_table(&self) -> bool {
1029
5.38k
        self.tables.len() < self.config.max_tables
1030
5.38k
    }
1031
1032
6.82k
    fn can_add_local_or_import_global(&self) -> bool {
1033
6.82k
        self.globals.len() < self.config.max_globals
1034
6.82k
    }
1035
1036
5.76k
    fn can_add_local_or_import_memory(&self) -> bool {
1037
5.76k
        self.memories.len() < self.config.max_memories
1038
5.76k
    }
1039
1040
5.67k
    fn arbitrary_imports(&mut self, u: &mut Unstructured) -> Result<()> {
1041
5.67k
        if self.config.max_type_size < self.type_size {
1042
0
            return Ok(());
1043
5.67k
        }
1044
5.67k
1045
5.67k
        let mut import_strings = HashSet::new();
1046
5.67k
        let mut choices: Vec<fn(&mut Unstructured, &mut Module) -> Result<EntityType>> =
1047
5.67k
            Vec::with_capacity(5);
1048
5.67k
        let min = self.config.min_imports.saturating_sub(self.num_imports);
1049
5.67k
        let max = self.config.max_imports.saturating_sub(self.num_imports);
1050
5.67k
        arbitrary_loop(u, min, max, |u| {
1051
4.32k
            choices.clear();
1052
4.32k
            if self.can_add_local_or_import_tag() {
1053
0
                choices.push(|u, m| {
1054
0
                    let ty = m.arbitrary_tag_type(u)?;
1055
0
                    Ok(EntityType::Tag(ty))
1056
0
                });
1057
4.32k
            }
1058
4.32k
            if self.can_add_local_or_import_func() {
1059
1.91k
                choices.push(|u, m| {
1060
1.56k
                    let idx = *u.choose(&m.func_types)?;
1061
1.56k
                    let ty = m.func_type(idx).clone();
1062
1.56k
                    Ok(EntityType::Func(idx, ty))
1063
1.91k
                });
1064
2.41k
            }
1065
4.32k
            if self.can_add_local_or_import_global() {
1066
4.32k
                choices.push(|u, m| {
1067
2.13k
                    let ty = m.arbitrary_global_type(u)?;
1068
2.13k
                    Ok(EntityType::Global(ty))
1069
4.32k
                });
1070
4.32k
            }
1071
4.32k
            if self.can_add_local_or_import_memory() {
1072
2.97k
                choices.push(|u, m| {
1073
336
                    let ty = arbitrary_memtype(u, m.config())?;
1074
336
                    Ok(EntityType::Memory(ty))
1075
2.97k
                });
1076
2.97k
            }
1077
4.32k
            if self.can_add_local_or_import_table() {
1078
2.34k
                choices.push(|u, m| {
1079
288
                    let ty = arbitrary_table_type(u, m.config(), Some(m))?;
1080
288
                    Ok(EntityType::Table(ty))
1081
2.34k
                });
1082
2.34k
            }
1083
1084
4.32k
            if choices.is_empty() {
1085
                // We are out of choices. If we have not have reached the
1086
                // minimum yet, then we have no way to satisfy the constraint,
1087
                // but we follow max-constraints before the min-import
1088
                // constraint.
1089
0
                return Ok(false);
1090
4.32k
            }
1091
1092
            // Generate a type to import, but only actually add the item if the
1093
            // type size budget allows us to.
1094
4.32k
            let f = u.choose(&choices)?;
1095
4.32k
            let entity_type = f(u, self)?;
1096
4.32k
            let budget = self.config.max_type_size - self.type_size;
1097
4.32k
            if entity_type.size() + 1 > budget {
1098
2
                return Ok(false);
1099
4.32k
            }
1100
4.32k
            self.type_size += entity_type.size() + 1;
1101
1102
            // Generate an arbitrary module/name pair to name this import.
1103
4.32k
            let mut import_pair = unique_import_strings(1_000, u)?;
1104
4.32k
            if self.duplicate_imports_behavior == DuplicateImportsBehavior::Disallowed {
1105
0
                while import_strings.contains(&import_pair) {
1106
0
                    use std::fmt::Write;
1107
0
                    write!(&mut import_pair.1, "{}", import_strings.len()).unwrap();
1108
0
                }
1109
0
                import_strings.insert(import_pair.clone());
1110
4.32k
            }
1111
4.32k
            let (module, field) = import_pair;
1112
4.32k
1113
4.32k
            // Once our name is determined, then we push the typed item into the
1114
4.32k
            // appropriate namespace.
1115
4.32k
            match &entity_type {
1116
0
                EntityType::Tag(ty) => self.tags.push(ty.clone()),
1117
1.56k
                EntityType::Func(idx, ty) => self.funcs.push((*idx, ty.clone())),
1118
2.13k
                EntityType::Global(ty) => self.globals.push(*ty),
1119
288
                EntityType::Table(ty) => self.tables.push(*ty),
1120
336
                EntityType::Memory(ty) => self.memories.push(*ty),
1121
            }
1122
1123
4.32k
            self.num_imports += 1;
1124
4.32k
            self.imports.push(Import {
1125
4.32k
                module,
1126
4.32k
                field,
1127
4.32k
                entity_type,
1128
4.32k
            });
1129
4.32k
            Ok(true)
1130
5.67k
        })?;
1131
1132
5.67k
        Ok(())
1133
5.67k
    }
1134
1135
    /// Generate some arbitrary imports from the list of available imports.
1136
    ///
1137
    /// Returns `true` if there was a list of available imports
1138
    /// configured. Otherwise `false` and the caller should generate arbitrary
1139
    /// imports.
1140
5.67k
    fn arbitrary_imports_from_available(&mut self, u: &mut Unstructured) -> Result<bool> {
1141
5.67k
        let example_module = if let Some(wasm) = self.config.available_imports.take() {
1142
0
            wasm
1143
        } else {
1144
5.67k
            return Ok(false);
1145
        };
1146
1147
        #[cfg(feature = "wasmparser")]
1148
        {
1149
            self._arbitrary_imports_from_available(u, &example_module)?;
1150
            Ok(true)
1151
        }
1152
        #[cfg(not(feature = "wasmparser"))]
1153
        {
1154
0
            let _ = (example_module, u);
1155
0
            panic!("support for `available_imports` was disabled at compile time");
1156
        }
1157
5.67k
    }
1158
1159
    #[cfg(feature = "wasmparser")]
1160
    fn _arbitrary_imports_from_available(
1161
        &mut self,
1162
        u: &mut Unstructured,
1163
        example_module: &[u8],
1164
    ) -> Result<()> {
1165
        // First, parse the module-by-example to collect the types and imports.
1166
        //
1167
        // `available_types` will map from a signature index (which is the same as the index into
1168
        // this vector) as it appears in the parsed code, to the type itself as well as to the
1169
        // index in our newly generated module. Initially the option is `None` and will become a
1170
        // `Some` when we encounter an import that uses this signature in the next portion of this
1171
        // function. See also the `make_func_type` closure below.
1172
        let mut available_types = Vec::new();
1173
        let mut available_imports = Vec::<wasmparser::Import>::new();
1174
        for payload in wasmparser::Parser::new(0).parse_all(&example_module) {
1175
            match payload.expect("could not parse the available import payload") {
1176
                wasmparser::Payload::TypeSection(type_reader) => {
1177
                    for ty in type_reader.into_iter_err_on_gc_types() {
1178
                        let ty = ty.expect("could not parse type section");
1179
                        available_types.push((ty, None));
1180
                    }
1181
                }
1182
                wasmparser::Payload::ImportSection(import_reader) => {
1183
                    for im in import_reader {
1184
                        let im = im.expect("could not read import");
1185
                        // We can immediately filter whether this is an import we want to
1186
                        // use.
1187
                        let use_import = u.arbitrary().unwrap_or(false);
1188
                        if !use_import {
1189
                            continue;
1190
                        }
1191
                        available_imports.push(im);
1192
                    }
1193
                }
1194
                _ => {}
1195
            }
1196
        }
1197
1198
        // In this function we need to place imported function/tag types in the types section and
1199
        // generate import entries (which refer to said types) at the same time.
1200
        let max_types = self.config.max_types;
1201
        let multi_value_enabled = self.config.multi_value_enabled;
1202
        let mut new_imports = Vec::with_capacity(available_imports.len());
1203
        let first_type_index = self.types.len();
1204
        let mut new_types = Vec::<SubType>::new();
1205
1206
        // Returns the index to the translated type in the to-be type section, and the reference to
1207
        // the type itself.
1208
        let mut make_func_type = |parsed_sig_idx: u32| {
1209
            let serialized_sig_idx = match available_types.get_mut(parsed_sig_idx as usize) {
1210
                None => panic!("signature index refers to a type out of bounds"),
1211
                Some((_, Some(idx))) => *idx as usize,
1212
                Some((func_type, index_store)) => {
1213
                    let multi_value_required = func_type.results().len() > 1;
1214
                    let new_index = first_type_index + new_types.len();
1215
                    if new_index >= max_types || (multi_value_required && !multi_value_enabled) {
1216
                        return None;
1217
                    }
1218
                    let func_type = Rc::new(FuncType {
1219
                        params: func_type
1220
                            .params()
1221
                            .iter()
1222
                            .map(|t| (*t).try_into().unwrap())
1223
                            .collect(),
1224
                        results: func_type
1225
                            .results()
1226
                            .iter()
1227
                            .map(|t| (*t).try_into().unwrap())
1228
                            .collect(),
1229
                    });
1230
                    index_store.replace(new_index as u32);
1231
                    new_types.push(SubType {
1232
                        is_final: true,
1233
                        supertype: None,
1234
                        composite_type: CompositeType::Func(Rc::clone(&func_type)),
1235
                    });
1236
                    new_index
1237
                }
1238
            };
1239
            match &new_types[serialized_sig_idx - first_type_index].composite_type {
1240
                CompositeType::Func(f) => Some((serialized_sig_idx as u32, Rc::clone(f))),
1241
                _ => unimplemented!(),
1242
            }
1243
        };
1244
1245
        for import in available_imports {
1246
            let type_size_budget = self.config.max_type_size - self.type_size;
1247
            let entity_type = match &import.ty {
1248
                wasmparser::TypeRef::Func(sig_idx) => {
1249
                    if self.funcs.len() >= self.config.max_funcs {
1250
                        continue;
1251
                    } else if let Some((sig_idx, func_type)) = make_func_type(*sig_idx) {
1252
                        let entity = EntityType::Func(sig_idx as u32, Rc::clone(&func_type));
1253
                        if type_size_budget < entity.size() {
1254
                            continue;
1255
                        }
1256
                        self.funcs.push((sig_idx, func_type));
1257
                        entity
1258
                    } else {
1259
                        continue;
1260
                    }
1261
                }
1262
1263
                wasmparser::TypeRef::Tag(wasmparser::TagType { func_type_idx, .. }) => {
1264
                    let can_add_tag = self.tags.len() < self.config.max_tags;
1265
                    if !self.config.exceptions_enabled || !can_add_tag {
1266
                        continue;
1267
                    } else if let Some((sig_idx, func_type)) = make_func_type(*func_type_idx) {
1268
                        let tag_type = TagType {
1269
                            func_type_idx: sig_idx,
1270
                            func_type,
1271
                        };
1272
                        let entity = EntityType::Tag(tag_type.clone());
1273
                        if type_size_budget < entity.size() {
1274
                            continue;
1275
                        }
1276
                        self.tags.push(tag_type);
1277
                        entity
1278
                    } else {
1279
                        continue;
1280
                    }
1281
                }
1282
1283
                wasmparser::TypeRef::Table(table_ty) => {
1284
                    let table_ty = TableType::try_from(*table_ty).unwrap();
1285
                    let entity = EntityType::Table(table_ty);
1286
                    let type_size = entity.size();
1287
                    if type_size_budget < type_size || !self.can_add_local_or_import_table() {
1288
                        continue;
1289
                    }
1290
                    self.type_size += type_size;
1291
                    self.tables.push(table_ty);
1292
                    entity
1293
                }
1294
1295
                wasmparser::TypeRef::Memory(memory_ty) => {
1296
                    let memory_ty = MemoryType::try_from(*memory_ty).unwrap();
1297
                    let entity = EntityType::Memory(memory_ty);
1298
                    let type_size = entity.size();
1299
                    if type_size_budget < type_size || !self.can_add_local_or_import_memory() {
1300
                        continue;
1301
                    }
1302
                    self.type_size += type_size;
1303
                    self.memories.push(memory_ty);
1304
                    entity
1305
                }
1306
1307
                wasmparser::TypeRef::Global(global_ty) => {
1308
                    let global_ty = (*global_ty).try_into().unwrap();
1309
                    let entity = EntityType::Global(global_ty);
1310
                    let type_size = entity.size();
1311
                    if type_size_budget < type_size || !self.can_add_local_or_import_global() {
1312
                        continue;
1313
                    }
1314
                    self.type_size += type_size;
1315
                    self.globals.push(global_ty);
1316
                    entity
1317
                }
1318
            };
1319
            new_imports.push(Import {
1320
                module: import.module.to_string(),
1321
                field: import.name.to_string(),
1322
                entity_type,
1323
            });
1324
            self.num_imports += 1;
1325
        }
1326
1327
        // Finally, add the entities we just generated.
1328
        for ty in new_types {
1329
            self.rec_groups.push(self.types.len()..self.types.len() + 1);
1330
            self.add_type(ty);
1331
        }
1332
        self.imports.extend(new_imports);
1333
1334
        Ok(())
1335
    }
1336
1337
24.8k
    fn type_of(&self, kind: ExportKind, index: u32) -> EntityType {
1338
24.8k
        match kind {
1339
5.78k
            ExportKind::Global => EntityType::Global(self.globals[index as usize]),
1340
3.11k
            ExportKind::Memory => EntityType::Memory(self.memories[index as usize]),
1341
2.23k
            ExportKind::Table => EntityType::Table(self.tables[index as usize]),
1342
            ExportKind::Func => {
1343
13.7k
                let (_idx, ty) = &self.funcs[index as usize];
1344
13.7k
                EntityType::Func(u32::max_value(), ty.clone())
1345
            }
1346
0
            ExportKind::Tag => EntityType::Tag(self.tags[index as usize].clone()),
1347
        }
1348
24.8k
    }
1349
1350
35.9k
    fn ty(&self, idx: u32) -> &SubType {
1351
35.9k
        &self.types[idx as usize]
1352
35.9k
    }
1353
1354
14.2k
    fn func_types(&self) -> impl Iterator<Item = (u32, &FuncType)> + '_ {
1355
14.2k
        self.func_types
1356
14.2k
            .iter()
1357
14.2k
            .copied()
1358
16.6k
            .map(move |type_i| (type_i, &**self.func_type(type_i)))
1359
14.2k
    }
1360
1361
35.9k
    fn func_type(&self, idx: u32) -> &Rc<FuncType> {
1362
35.9k
        match &self.ty(idx).composite_type {
1363
35.9k
            CompositeType::Func(f) => f,
1364
0
            _ => panic!("types[{idx}] is not a func type"),
1365
        }
1366
35.9k
    }
1367
1368
5.67k
    fn tags(&self) -> impl Iterator<Item = (u32, &TagType)> + '_ {
1369
5.67k
        self.tags
1370
5.67k
            .iter()
1371
5.67k
            .enumerate()
1372
5.67k
            .map(move |(i, ty)| (i as u32, ty))
1373
5.67k
    }
1374
1375
15.6k
    fn funcs(&self) -> impl Iterator<Item = (u32, &Rc<FuncType>)> + '_ {
1376
15.6k
        self.funcs
1377
15.6k
            .iter()
1378
15.6k
            .enumerate()
1379
54.4k
            .map(move |(i, (_, ty))| (i as u32, ty))
1380
15.6k
    }
1381
1382
0
    fn has_tag_func_types(&self) -> bool {
1383
0
        self.tag_func_types().next().is_some()
1384
0
    }
1385
1386
0
    fn tag_func_types(&self) -> impl Iterator<Item = u32> + '_ {
1387
0
        self.func_types
1388
0
            .iter()
1389
0
            .copied()
1390
0
            .filter(move |i| self.func_type(*i).results.is_empty())
1391
0
    }
1392
1393
16.2k
    fn arbitrary_valtype(&self, u: &mut Unstructured) -> Result<ValType> {
1394
16.4k
        #[derive(Arbitrary)]
_RNCNvXNvNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtBc_6Module17arbitrary_valtype1__NtB6_12ValTypeClassNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9arbitrary0Be_
Line
Count
Source
1394
221
        #[derive(Arbitrary)]
_RNCNvXNvNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtBc_6Module17arbitrary_valtype1__NtB6_12ValTypeClassNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9arbitrarys_0Be_
Line
Count
Source
1394
16.2k
        #[derive(Arbitrary)]
_RNCNvXNvNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtBc_6Module17arbitrary_valtype1__NtB6_12ValTypeClassNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9arbitrarys0_0Be_
Line
Count
Source
1394
221
        #[derive(Arbitrary)]
Unexecuted instantiation: _RNCNvXNvNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtBc_6Module17arbitrary_valtype1__NtB6_12ValTypeClassNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_rest0Be_
Unexecuted instantiation: _RNCNvXNvNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtBc_6Module17arbitrary_valtype1__NtB6_12ValTypeClassNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_rests_0Be_
Unexecuted instantiation: _RNCNvXNvNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtBc_6Module17arbitrary_valtype1__NtB6_12ValTypeClassNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary19arbitrary_take_rests0_0Be_
Unexecuted instantiation: _RNCNvXNvNvMs3_NtCs4eJdYXiOSk9_10wasm_smith4coreNtBc_6Module17arbitrary_valtype1__NtB6_12ValTypeClassNtCsgsv2Y6Qu5CW_9arbitrary9Arbitrary9size_hint0Be_
1395
16.2k
        enum ValTypeClass {
1396
16.2k
            I32,
1397
16.2k
            I64,
1398
16.2k
            F32,
1399
16.2k
            F64,
1400
16.2k
            V128,
1401
16.2k
            Ref,
1402
16.2k
        }
1403
16.2k
1404
16.2k
        match u.arbitrary::<ValTypeClass>()? {
1405
3.94k
            ValTypeClass::I32 => Ok(ValType::I32),
1406
2.61k
            ValTypeClass::I64 => Ok(ValType::I64),
1407
2.03k
            ValTypeClass::F32 => Ok(ValType::F32),
1408
1.49k
            ValTypeClass::F64 => Ok(ValType::F64),
1409
            ValTypeClass::V128 => {
1410
1.47k
                if self.config.simd_enabled {
1411
0
                    Ok(ValType::V128)
1412
                } else {
1413
1.47k
                    Ok(ValType::I32)
1414
                }
1415
            }
1416
            ValTypeClass::Ref => {
1417
4.66k
                if self.config.reference_types_enabled {
1418
0
                    Ok(ValType::Ref(self.arbitrary_ref_type(u)?))
1419
                } else {
1420
4.66k
                    Ok(ValType::I32)
1421
                }
1422
            }
1423
        }
1424
16.2k
    }
1425
1426
4.63k
    fn arbitrary_global_type(&self, u: &mut Unstructured) -> Result<GlobalType> {
1427
4.63k
        Ok(GlobalType {
1428
4.63k
            val_type: self.arbitrary_valtype(u)?,
1429
4.63k
            mutable: u.arbitrary()?,
1430
            shared: false,
1431
        })
1432
4.63k
    }
1433
1434
0
    fn arbitrary_tag_type(&self, u: &mut Unstructured) -> Result<TagType> {
1435
0
        let candidate_func_types: Vec<_> = self.tag_func_types().collect();
1436
0
        arbitrary_tag_type(u, &candidate_func_types, |ty_idx| {
1437
0
            self.func_type(ty_idx).clone()
1438
0
        })
1439
0
    }
1440
1441
5.67k
    fn arbitrary_tags(&mut self, u: &mut Unstructured) -> Result<()> {
1442
5.67k
        if !self.config.exceptions_enabled || !self.has_tag_func_types() {
1443
5.67k
            return Ok(());
1444
0
        }
1445
0
1446
0
        arbitrary_loop(u, self.config.min_tags, self.config.max_tags, |u| {
1447
0
            if !self.can_add_local_or_import_tag() {
1448
0
                return Ok(false);
1449
0
            }
1450
0
            self.tags.push(self.arbitrary_tag_type(u)?);
1451
0
            self.num_defined_tags += 1;
1452
0
            Ok(true)
1453
0
        })
1454
5.67k
    }
1455
1456
5.67k
    fn arbitrary_funcs(&mut self, u: &mut Unstructured) -> Result<()> {
1457
5.67k
        if self.func_types.is_empty() {
1458
1.11k
            return Ok(());
1459
4.56k
        }
1460
4.56k
1461
15.8k
        arbitrary_loop(u, self.config.min_funcs, self.config.max_funcs, |u| {
1462
15.8k
            if !self.can_add_local_or_import_func() {
1463
2
                return Ok(false);
1464
15.8k
            }
1465
15.8k
            let max = self.func_types.len() - 1;
1466
15.8k
            let ty = self.func_types[u.int_in_range(0..=max)?];
1467
15.8k
            self.funcs.push((ty, self.func_type(ty).clone()));
1468
15.8k
            self.num_defined_funcs += 1;
1469
15.8k
            Ok(true)
1470
15.8k
        })
1471
5.67k
    }
1472
1473
5.67k
    fn arbitrary_tables(&mut self, u: &mut Unstructured) -> Result<()> {
1474
5.67k
        arbitrary_loop(
1475
5.67k
            u,
1476
5.67k
            self.config.min_tables as usize,
1477
5.67k
            self.config.max_tables as usize,
1478
5.67k
            |u| {
1479
1.06k
                if !self.can_add_local_or_import_table() {
1480
21
                    return Ok(false);
1481
1.03k
                }
1482
1.03k
                let ty = arbitrary_table_type(u, self.config(), Some(self))?;
1483
1.03k
                let init = self.arbitrary_table_init(u, ty.element_type)?;
1484
1.03k
                self.defined_tables.push(init);
1485
1.03k
                self.tables.push(ty);
1486
1.03k
                Ok(true)
1487
5.67k
            },
1488
5.67k
        )
1489
5.67k
    }
1490
1491
    /// Generates an arbitrary table initialization expression for a table whose
1492
    /// element type is `ty`.
1493
    ///
1494
    /// Table initialization expressions were added by the GC proposal to
1495
    /// initialize non-nullable tables.
1496
1.03k
    fn arbitrary_table_init(
1497
1.03k
        &mut self,
1498
1.03k
        u: &mut Unstructured,
1499
1.03k
        ty: RefType,
1500
1.03k
    ) -> Result<Option<ConstExpr>> {
1501
1.03k
        if !self.config.gc_enabled {
1502
1.03k
            assert!(ty.nullable);
1503
1.03k
            return Ok(None);
1504
0
        }
1505
0
        // Even with the GC proposal an initialization expression is not
1506
0
        // required if the element type is nullable.
1507
0
        if ty.nullable && u.arbitrary()? {
1508
0
            return Ok(None);
1509
0
        }
1510
0
        let expr = self.arbitrary_const_expr(ValType::Ref(ty), u)?;
1511
0
        Ok(Some(expr))
1512
1.03k
    }
1513
1514
5.67k
    fn arbitrary_memories(&mut self, u: &mut Unstructured) -> Result<()> {
1515
5.67k
        arbitrary_loop(
1516
5.67k
            u,
1517
5.67k
            self.config.min_memories as usize,
1518
5.67k
            self.config.max_memories as usize,
1519
5.67k
            |u| {
1520
1.43k
                if !self.can_add_local_or_import_memory() {
1521
23
                    return Ok(false);
1522
1.41k
                }
1523
1.41k
                self.num_defined_memories += 1;
1524
1.41k
                self.memories.push(arbitrary_memtype(u, self.config())?);
1525
1.41k
                Ok(true)
1526
5.67k
            },
1527
5.67k
        )
1528
5.67k
    }
1529
1530
    /// Add a new global of the given type and return its global index.
1531
2.50k
    fn add_arbitrary_global_of_type(
1532
2.50k
        &mut self,
1533
2.50k
        ty: GlobalType,
1534
2.50k
        u: &mut Unstructured,
1535
2.50k
    ) -> Result<u32> {
1536
2.50k
        let expr = self.arbitrary_const_expr(ty.val_type, u)?;
1537
2.50k
        let global_idx = self.globals.len() as u32;
1538
2.50k
        self.globals.push(ty);
1539
2.50k
        self.defined_globals.push((global_idx, expr));
1540
2.50k
        Ok(global_idx)
1541
2.50k
    }
1542
1543
    /// Generates an arbitrary constant expression of the type `ty`.
1544
2.50k
    fn arbitrary_const_expr(&mut self, ty: ValType, u: &mut Unstructured) -> Result<ConstExpr> {
1545
2.50k
        let mut choices = mem::take(&mut self.const_expr_choices);
1546
2.50k
        choices.clear();
1547
2.50k
        let num_funcs = self.funcs.len() as u32;
1548
1549
        // MVP wasm can `global.get` any immutable imported global in a
1550
        // constant expression, and the GC proposal enables this for all
1551
        // globals, so make all matching globals a candidate.
1552
2.50k
        for i in self.globals_for_const_expr(ty) {
1553
793
            choices.push(Box::new(move |_, _| Ok(ConstExpr::global_get(i))));
1554
793
        }
1555
1556
        // Another option for all types is to have an actual value of each type.
1557
        // Change `ty` to any valid subtype of `ty` and then generate a matching
1558
        // type of that value.
1559
2.50k
        let ty = self.arbitrary_matching_val_type(u, ty)?;
1560
2.50k
        match ty {
1561
1.67k
            ValType::I32 => choices.push(Box::new(|u, _| Ok(ConstExpr::i32_const(u.arbitrary()?)))),
1562
323
            ValType::I64 => choices.push(Box::new(|u, _| Ok(ConstExpr::i64_const(u.arbitrary()?)))),
1563
322
            ValType::F32 => choices.push(Box::new(|u, _| Ok(ConstExpr::f32_const(u.arbitrary()?)))),
1564
184
            ValType::F64 => choices.push(Box::new(|u, _| Ok(ConstExpr::f64_const(u.arbitrary()?)))),
1565
            ValType::V128 => {
1566
0
                choices.push(Box::new(|u, _| Ok(ConstExpr::v128_const(u.arbitrary()?))))
1567
            }
1568
1569
0
            ValType::Ref(ty) => {
1570
0
                if ty.nullable {
1571
0
                    choices.push(Box::new(move |_, _| Ok(ConstExpr::ref_null(ty.heap_type))));
1572
0
                }
1573
1574
0
                match ty.heap_type {
1575
0
                    HeapType::Func if num_funcs > 0 => {
1576
0
                        choices.push(Box::new(move |u, _| {
1577
0
                            let func = u.int_in_range(0..=num_funcs - 1)?;
1578
0
                            Ok(ConstExpr::ref_func(func))
1579
0
                        }));
1580
0
                    }
1581
1582
0
                    HeapType::Concrete(ty) => {
1583
0
                        for (i, fty) in self.funcs.iter().map(|(t, _)| *t).enumerate() {
1584
0
                            if ty != fty {
1585
0
                                continue;
1586
0
                            }
1587
0
                            choices.push(Box::new(move |_, _| Ok(ConstExpr::ref_func(i as u32))));
1588
0
                        }
1589
                    }
1590
1591
                    // TODO: fill out more GC types e.g `array.new` and
1592
                    // `struct.new`
1593
0
                    _ => {}
1594
                }
1595
            }
1596
        }
1597
1598
2.50k
        let f = u.choose(&choices)?;
1599
2.50k
        let ret = f(u, ty);
1600
2.50k
        self.const_expr_choices = choices;
1601
2.50k
        ret
1602
2.50k
    }
1603
1604
5.67k
    fn arbitrary_globals(&mut self, u: &mut Unstructured) -> Result<()> {
1605
5.67k
        arbitrary_loop(u, self.config.min_globals, self.config.max_globals, |u| {
1606
2.50k
            if !self.can_add_local_or_import_global() {
1607
0
                return Ok(false);
1608
2.50k
            }
1609
1610
2.50k
            let ty = self.arbitrary_global_type(u)?;
1611
2.50k
            self.add_arbitrary_global_of_type(ty, u)?;
1612
1613
2.50k
            Ok(true)
1614
5.67k
        })
1615
5.67k
    }
1616
1617
5.67k
    fn required_exports(&mut self, u: &mut Unstructured) -> Result<bool> {
1618
5.67k
        let example_module = if let Some(wasm) = self.config.exports.clone() {
1619
0
            wasm
1620
        } else {
1621
5.67k
            return Ok(false);
1622
        };
1623
1624
        #[cfg(feature = "wasmparser")]
1625
        {
1626
            self._required_exports(u, &example_module)?;
1627
            Ok(true)
1628
        }
1629
        #[cfg(not(feature = "wasmparser"))]
1630
        {
1631
0
            let _ = (example_module, u);
1632
0
            panic!("support for `exports` was disabled at compile time");
1633
        }
1634
5.67k
    }
1635
1636
    #[cfg(feature = "wasmparser")]
1637
    fn _required_exports(&mut self, u: &mut Unstructured, example_module: &[u8]) -> Result<()> {
1638
        fn convert_heap_type(ty: &wasmparser::HeapType) -> HeapType {
1639
            match ty {
1640
                wasmparser::HeapType::Concrete(_) => {
1641
                    panic!("Unable to handle concrete types in exports")
1642
                }
1643
                wasmparser::HeapType::Func => HeapType::Func,
1644
                wasmparser::HeapType::Extern => HeapType::Extern,
1645
                wasmparser::HeapType::Any => HeapType::Any,
1646
                wasmparser::HeapType::None => HeapType::None,
1647
                wasmparser::HeapType::NoExtern => HeapType::NoExtern,
1648
                wasmparser::HeapType::NoFunc => HeapType::NoFunc,
1649
                wasmparser::HeapType::Eq => HeapType::Eq,
1650
                wasmparser::HeapType::Struct => HeapType::Struct,
1651
                wasmparser::HeapType::Array => HeapType::Array,
1652
                wasmparser::HeapType::I31 => HeapType::I31,
1653
                wasmparser::HeapType::Exn => HeapType::Exn,
1654
                wasmparser::HeapType::NoExn => HeapType::NoExn,
1655
            }
1656
        }
1657
1658
        fn convert_val_type(ty: &wasmparser::ValType) -> ValType {
1659
            match ty {
1660
                wasmparser::ValType::I32 => ValType::I32,
1661
                wasmparser::ValType::I64 => ValType::I64,
1662
                wasmparser::ValType::F32 => ValType::F32,
1663
                wasmparser::ValType::F64 => ValType::F64,
1664
                wasmparser::ValType::V128 => ValType::V128,
1665
                wasmparser::ValType::Ref(r) => ValType::Ref(RefType {
1666
                    nullable: r.is_nullable(),
1667
                    heap_type: convert_heap_type(&r.heap_type()),
1668
                }),
1669
            }
1670
        }
1671
1672
        fn convert_export_kind(kind: &wasmparser::ExternalKind) -> ExportKind {
1673
            match kind {
1674
                wasmparser::ExternalKind::Func => ExportKind::Func,
1675
                wasmparser::ExternalKind::Table => ExportKind::Table,
1676
                wasmparser::ExternalKind::Memory => ExportKind::Memory,
1677
                wasmparser::ExternalKind::Global => ExportKind::Global,
1678
                wasmparser::ExternalKind::Tag => ExportKind::Tag,
1679
            }
1680
        }
1681
1682
        let mut required_exports: Vec<wasmparser::Export> = vec![];
1683
        let mut validator = wasmparser::Validator::new();
1684
        let exports_types = validator
1685
            .validate_all(&example_module)
1686
            .expect("Failed to validate `exports` Wasm");
1687
        for payload in wasmparser::Parser::new(0).parse_all(&example_module) {
1688
            match payload.expect("Failed to read `exports` Wasm") {
1689
                wasmparser::Payload::ExportSection(export_reader) => {
1690
                    required_exports = export_reader
1691
                        .into_iter()
1692
                        .collect::<Result<_, _>>()
1693
                        .expect("Failed to read `exports` export section");
1694
                }
1695
                _ => {}
1696
            }
1697
        }
1698
1699
        // For each export, add necessary prerequisites to the module.
1700
        for export in required_exports {
1701
            let new_index = match exports_types
1702
                .entity_type_from_export(&export)
1703
                .unwrap_or_else(|| {
1704
                    panic!(
1705
                        "Unable to get type from export {:?} in `exports` Wasm",
1706
                        export,
1707
                    )
1708
                }) {
1709
                // For functions, add the type and a function with that type.
1710
                wasmparser::types::EntityType::Func(id) => {
1711
                    let subtype = exports_types.get(id).unwrap_or_else(|| {
1712
                        panic!(
1713
                            "Unable to get subtype for function {:?} in `exports` Wasm",
1714
                            id
1715
                        )
1716
                    });
1717
                    match &subtype.composite_type {
1718
                        wasmparser::CompositeType::Func(func_type) => {
1719
                            assert!(
1720
                                subtype.is_final,
1721
                                "Subtype {:?} from `exports` Wasm is not final",
1722
                                subtype
1723
                            );
1724
                            assert!(
1725
                                subtype.supertype_idx.is_none(),
1726
                                "Subtype {:?} from `exports` Wasm has non-empty supertype",
1727
                                subtype
1728
                            );
1729
                            let new_type = Rc::new(FuncType {
1730
                                params: func_type
1731
                                    .params()
1732
                                    .into_iter()
1733
                                    .map(convert_val_type)
1734
                                    .collect(),
1735
                                results: func_type
1736
                                    .results()
1737
                                    .into_iter()
1738
                                    .map(convert_val_type)
1739
                                    .collect(),
1740
                            });
1741
                            self.rec_groups.push(self.types.len()..self.types.len() + 1);
1742
                            let type_index = self.add_type(SubType {
1743
                                is_final: true,
1744
                                supertype: None,
1745
                                composite_type: CompositeType::Func(Rc::clone(&new_type)),
1746
                            });
1747
                            let func_index = self.funcs.len() as u32;
1748
                            self.funcs.push((type_index, new_type));
1749
                            self.num_defined_funcs += 1;
1750
                            func_index
1751
                        }
1752
                        _ => panic!(
1753
                            "Unable to handle type {:?} from `exports` Wasm",
1754
                            subtype.composite_type
1755
                        ),
1756
                    }
1757
                }
1758
                // For globals, add a new global.
1759
                wasmparser::types::EntityType::Global(global_type) => self
1760
                    .add_arbitrary_global_of_type(
1761
                        GlobalType {
1762
                            val_type: convert_val_type(&global_type.content_type),
1763
                            mutable: global_type.mutable,
1764
                            shared: global_type.shared,
1765
                        },
1766
                        u,
1767
                    )?,
1768
                wasmparser::types::EntityType::Table(_)
1769
                | wasmparser::types::EntityType::Memory(_)
1770
                | wasmparser::types::EntityType::Tag(_) => {
1771
                    panic!(
1772
                        "Config `exports` has an export of type {:?} which cannot yet be handled.",
1773
                        export.kind
1774
                    )
1775
                }
1776
            };
1777
            self.exports.push((
1778
                export.name.to_string(),
1779
                convert_export_kind(&export.kind),
1780
                new_index,
1781
            ));
1782
            self.export_names.insert(export.name.to_string());
1783
        }
1784
1785
        Ok(())
1786
    }
1787
1788
5.67k
    fn arbitrary_exports(&mut self, u: &mut Unstructured) -> Result<()> {
1789
5.67k
        if self.config.max_type_size < self.type_size && !self.config.export_everything {
1790
0
            return Ok(());
1791
5.67k
        }
1792
5.67k
1793
5.67k
        // Build up a list of candidates for each class of import
1794
5.67k
        let mut choices: Vec<Vec<(ExportKind, u32)>> = Vec::with_capacity(6);
1795
5.67k
        choices.push(
1796
5.67k
            (0..self.funcs.len())
1797
17.3k
                .map(|i| (ExportKind::Func, i as u32))
1798
5.67k
                .collect(),
1799
5.67k
        );
1800
5.67k
        choices.push(
1801
5.67k
            (0..self.tables.len())
1802
5.67k
                .map(|i| (ExportKind::Table, i as u32))
1803
5.67k
                .collect(),
1804
5.67k
        );
1805
5.67k
        choices.push(
1806
5.67k
            (0..self.memories.len())
1807
5.67k
                .map(|i| (ExportKind::Memory, i as u32))
1808
5.67k
                .collect(),
1809
5.67k
        );
1810
5.67k
        choices.push(
1811
5.67k
            (0..self.globals.len())
1812
5.67k
                .map(|i| (ExportKind::Global, i as u32))
1813
5.67k
                .collect(),
1814
5.67k
        );
1815
5.67k
1816
5.67k
        // If the configuration demands exporting everything, we do so here and
1817
5.67k
        // early-return.
1818
5.67k
        if self.config.export_everything {
1819
0
            for choices_by_kind in choices {
1820
0
                for (kind, idx) in choices_by_kind {
1821
0
                    let name = unique_string(1_000, &mut self.export_names, u)?;
1822
0
                    self.add_arbitrary_export(name, kind, idx)?;
1823
                }
1824
            }
1825
0
            return Ok(());
1826
5.67k
        }
1827
5.67k
1828
5.67k
        arbitrary_loop(u, self.config.min_exports, self.config.max_exports, |u| {
1829
5.21k
            // Remove all candidates for export whose type size exceeds our
1830
5.21k
            // remaining budget for type size. Then also remove any classes
1831
5.21k
            // of exports which no longer have any candidates.
1832
5.21k
            //
1833
5.21k
            // If there's nothing remaining after this, then we're done.
1834
5.21k
            let max_size = self.config.max_type_size - self.type_size;
1835
8.81k
            for list in choices.iter_mut() {
1836
19.3k
                list.retain(|(kind, idx)| self.type_of(*kind, *idx).size() + 1 < max_size);
1837
8.81k
            }
1838
8.81k
            choices.retain(|list| !list.is_empty());
1839
5.21k
            if choices.is_empty() {
1840
8
                return Ok(false);
1841
5.20k
            }
1842
1843
            // Pick a name, then pick the export, and then we can record
1844
            // information about the chosen export.
1845
5.20k
            let name = unique_string(1_000, &mut self.export_names, u)?;
1846
5.20k
            let list = u.choose(&choices)?;
1847
5.20k
            let (kind, idx) = *u.choose(list)?;
1848
5.20k
            self.add_arbitrary_export(name, kind, idx)?;
1849
5.20k
            Ok(true)
1850
5.67k
        })
1851
5.67k
    }
1852
1853
5.46k
    fn add_arbitrary_export(&mut self, name: String, kind: ExportKind, idx: u32) -> Result<()> {
1854
5.46k
        let ty = self.type_of(kind, idx);
1855
5.46k
        self.type_size += 1 + ty.size();
1856
5.46k
        if self.type_size <= self.config.max_type_size {
1857
5.46k
            self.exports.push((name, kind, idx));
1858
5.46k
            Ok(())
1859
        } else {
1860
            // If our addition of exports takes us above the allowed number of
1861
            // types, we fail; this error code is not the most illustrative of
1862
            // the cause but is the best available from `arbitrary`.
1863
0
            Err(arbitrary::Error::IncorrectFormat)
1864
        }
1865
5.46k
    }
1866
1867
5.67k
    fn arbitrary_start(&mut self, u: &mut Unstructured) -> Result<()> {
1868
5.67k
        if !self.config.allow_start_export {
1869
0
            return Ok(());
1870
5.67k
        }
1871
5.67k
1872
5.67k
        let mut choices = Vec::with_capacity(self.funcs.len() as usize);
1873
1874
17.3k
        for (func_idx, ty) in self.funcs() {
1875
17.3k
            if ty.params.is_empty() && ty.results.is_empty() {
1876
10.2k
                choices.push(func_idx);
1877
10.2k
            }
1878
        }
1879
1880
5.67k
        if !choices.is_empty() && u.arbitrary().unwrap_or(false) {
1881
582
            let f = *u.choose(&choices)?;
1882
582
            self.start = Some(f);
1883
5.09k
        }
1884
1885
5.67k
        Ok(())
1886
5.67k
    }
1887
1888
5.67k
    fn arbitrary_elems(&mut self, u: &mut Unstructured) -> Result<()> {
1889
5.67k
        // Create a helper closure to choose an arbitrary offset.
1890
5.67k
        let mut global_i32 = vec![];
1891
5.67k
        let mut global_i64 = vec![];
1892
5.67k
        if !self.config.disallow_traps {
1893
5.67k
            for i in self.globals_for_const_expr(ValType::I32) {
1894
404
                global_i32.push(i);
1895
404
            }
1896
5.67k
            for i in self.globals_for_const_expr(ValType::I64) {
1897
242
                global_i64.push(i);
1898
242
            }
1899
0
        }
1900
5.67k
        let disallow_traps = self.config.disallow_traps;
1901
5.67k
        let arbitrary_active_elem =
1902
1.58k
            |u: &mut Unstructured, min_mem_size: u64, table: Option<u32>, table_ty: &TableType| {
1903
1.58k
                let global_choices = if table_ty.table64 {
1904
0
                    &global_i64
1905
                } else {
1906
1.58k
                    &global_i32
1907
                };
1908
1.58k
                let (offset, max_size_hint) = if !global_choices.is_empty() && u.arbitrary()? {
1909
383
                    let g = u.choose(&global_choices)?;
1910
383
                    (Offset::Global(*g), None)
1911
                } else {
1912
1.20k
                    let max_mem_size = if disallow_traps {
1913
0
                        table_ty.minimum
1914
1.20k
                    } else if table_ty.table64 {
1915
0
                        u64::MAX
1916
                    } else {
1917
1.20k
                        u64::from(u32::MAX)
1918
                    };
1919
1.20k
                    let offset = arbitrary_offset(u, min_mem_size, max_mem_size, 0)?;
1920
1.20k
                    let max_size_hint = if disallow_traps
1921
1.20k
                        || (offset <= min_mem_size
1922
890
                            && u.int_in_range(0..=CHANCE_OFFSET_INBOUNDS)? != 0)
1923
                    {
1924
703
                        Some(min_mem_size - offset)
1925
                    } else {
1926
502
                        None
1927
                    };
1928
1929
1.20k
                    let offset = if table_ty.table64 {
1930
0
                        Offset::Const64(offset as i64)
1931
                    } else {
1932
1.20k
                        Offset::Const32(offset as i32)
1933
                    };
1934
1.20k
                    (offset, max_size_hint)
1935
                };
1936
1.58k
                Ok((ElementKind::Active { table, offset }, max_size_hint))
1937
1.58k
            };
1938
1939
        // Generate a list of candidates for "kinds" of elements segments. For
1940
        // example we can have an active segment for any existing table or
1941
        // passive/declared segments if the right wasm features are enabled.
1942
        type GenElemSegment<'a> =
1943
            dyn Fn(&mut Unstructured) -> Result<(ElementKind, Option<u64>)> + 'a;
1944
5.67k
        let mut choices: Vec<Box<GenElemSegment>> = Vec::new();
1945
5.67k
1946
5.67k
        // Bulk memory enables passive/declared segments, and note that the
1947
5.67k
        // types used are selected later.
1948
5.67k
        if self.config.bulk_memory_enabled {
1949
0
            choices.push(Box::new(|_| Ok((ElementKind::Passive, None))));
1950
0
            choices.push(Box::new(|_| Ok((ElementKind::Declared, None))));
1951
5.67k
        }
1952
1953
5.67k
        for (i, ty) in self.tables.iter().enumerate() {
1954
            // If this table starts with no capacity then any non-empty element
1955
            // segment placed onto it will immediately trap, which isn't too
1956
            // too interesting. If that's the case give it an unlikely chance
1957
            // of proceeding.
1958
1.32k
            if ty.minimum == 0 && u.int_in_range(0..=CHANCE_SEGMENT_ON_EMPTY)? != 0 {
1959
194
                continue;
1960
1.13k
            }
1961
1.13k
1962
1.13k
            let minimum = ty.minimum;
1963
1.13k
            // If the first table is a funcref table then it's a candidate for
1964
1.13k
            // the MVP encoding of element segments.
1965
1.13k
            let ty = *ty;
1966
1.13k
            if i == 0 && ty.element_type == RefType::FUNCREF {
1967
1.58k
                choices.push(Box::new(move |u| {
1968
1.58k
                    arbitrary_active_elem(u, minimum, None, &ty)
1969
1.58k
                }));
1970
1.13k
            }
1971
1.13k
            if self.config.bulk_memory_enabled {
1972
0
                let idx = Some(i as u32);
1973
0
                choices.push(Box::new(move |u| {
1974
0
                    arbitrary_active_elem(u, minimum, idx, &ty)
1975
0
                }));
1976
1.13k
            }
1977
        }
1978
1979
5.67k
        if choices.is_empty() {
1980
4.53k
            return Ok(());
1981
1.13k
        }
1982
1.13k
1983
1.13k
        arbitrary_loop(
1984
1.13k
            u,
1985
1.13k
            self.config.min_element_segments,
1986
1.13k
            self.config.max_element_segments,
1987
1.58k
            |u| {
1988
                // Pick a kind of element segment to generate which will also
1989
                // give us a hint of the maximum size, if any.
1990
1.58k
                let (kind, max_size_hint) = u.choose(&choices)?(u)?;
1991
1.58k
                let max = max_size_hint
1992
1.58k
                    .map(|i| usize::try_from(i).unwrap())
1993
1.58k
                    .unwrap_or_else(|| self.config.max_elements);
1994
1995
                // Infer, from the kind of segment, the type of the element
1996
                // segment. Passive/declared segments can be declared with any
1997
                // reference type, but active segments must match their table.
1998
1.58k
                let ty = match kind {
1999
0
                    ElementKind::Passive | ElementKind::Declared => self.arbitrary_ref_type(u)?,
2000
1.58k
                    ElementKind::Active { table, .. } => {
2001
1.58k
                        let idx = table.unwrap_or(0);
2002
1.58k
                        self.arbitrary_matching_ref_type(u, self.tables[idx as usize].element_type)?
2003
                    }
2004
                };
2005
2006
                // The `Elements::Functions` encoding is only possible when the
2007
                // element type is a `funcref` because the binary format can't
2008
                // allow encoding any other type in that form.
2009
1.58k
                let can_use_function_list = ty == RefType::FUNCREF;
2010
1.58k
                if !self.config.reference_types_enabled {
2011
1.58k
                    assert!(can_use_function_list);
2012
0
                }
2013
2014
                // If a function list is possible then build up a list of
2015
                // functions that can be selected from.
2016
1.58k
                let mut func_candidates = Vec::new();
2017
1.58k
                if can_use_function_list {
2018
1.58k
                    match ty.heap_type {
2019
1.58k
                        HeapType::Func => {
2020
1.58k
                            func_candidates.extend(0..self.funcs.len() as u32);
2021
1.58k
                        }
2022
0
                        HeapType::Concrete(ty) => {
2023
0
                            for (i, (fty, _)) in self.funcs.iter().enumerate() {
2024
0
                                if *fty == ty {
2025
0
                                    func_candidates.push(i as u32);
2026
0
                                }
2027
                            }
2028
                        }
2029
0
                        _ => {}
2030
                    }
2031
0
                }
2032
2033
                // And finally actually generate the arbitrary elements of this
2034
                // element segment. Function indices are used if they're either
2035
                // forced or allowed, and otherwise expressions are used
2036
                // instead.
2037
1.58k
                let items = if !self.config.reference_types_enabled
2038
0
                    || (can_use_function_list && u.arbitrary()?)
2039
                {
2040
1.58k
                    let mut init = vec![];
2041
1.58k
                    if func_candidates.len() > 0 {
2042
2.41k
                        arbitrary_loop(u, self.config.min_elements, max, |u| {
2043
2.41k
                            let func_idx = *u.choose(&func_candidates)?;
2044
2.41k
                            init.push(func_idx);
2045
2.41k
                            Ok(true)
2046
2.41k
                        })?;
2047
959
                    }
2048
1.58k
                    Elements::Functions(init)
2049
                } else {
2050
0
                    let mut init = vec![];
2051
0
                    arbitrary_loop(u, self.config.min_elements, max, |u| {
2052
0
                        init.push(self.arbitrary_const_expr(ValType::Ref(ty), u)?);
2053
0
                        Ok(true)
2054
0
                    })?;
2055
0
                    Elements::Expressions(init)
2056
                };
2057
2058
1.58k
                self.elems.push(ElementSegment { kind, ty, items });
2059
1.58k
                Ok(true)
2060
1.58k
            },
2061
1.13k
        )
2062
5.67k
    }
2063
2064
5.67k
    fn arbitrary_code(&mut self, u: &mut Unstructured) -> Result<()> {
2065
5.67k
        self.compute_interesting_values();
2066
5.67k
2067
5.67k
        self.code.reserve(self.num_defined_funcs);
2068
5.67k
        let mut allocs = CodeBuilderAllocations::new(self, self.config.exports.is_some());
2069
15.8k
        for (_, ty) in self.funcs[self.funcs.len() - self.num_defined_funcs..].iter() {
2070
15.8k
            let body = self.arbitrary_func_body(u, ty, &mut allocs)?;
2071
15.8k
            self.code.push(body);
2072
        }
2073
5.67k
        allocs.finish(u, self)?;
2074
5.67k
        Ok(())
2075
5.67k
    }
2076
2077
15.8k
    fn arbitrary_func_body(
2078
15.8k
        &self,
2079
15.8k
        u: &mut Unstructured,
2080
15.8k
        ty: &FuncType,
2081
15.8k
        allocs: &mut CodeBuilderAllocations,
2082
15.8k
    ) -> Result<Code> {
2083
15.8k
        let mut locals = self.arbitrary_locals(u)?;
2084
15.8k
        let builder = allocs.builder(ty, &mut locals);
2085
15.8k
        let instructions = if self.config.allow_invalid_funcs && u.arbitrary().unwrap_or(false) {
2086
0
            Instructions::Arbitrary(arbitrary_vec_u8(u)?)
2087
        } else {
2088
15.8k
            Instructions::Generated(builder.arbitrary(u, self)?)
2089
        };
2090
2091
15.8k
        Ok(Code {
2092
15.8k
            locals,
2093
15.8k
            instructions,
2094
15.8k
        })
2095
15.8k
    }
2096
2097
15.8k
    fn arbitrary_locals(&self, u: &mut Unstructured) -> Result<Vec<ValType>> {
2098
15.8k
        let mut ret = Vec::new();
2099
15.8k
        arbitrary_loop(u, 0, 100, |u| {
2100
3.10k
            ret.push(self.arbitrary_valtype(u)?);
2101
3.10k
            Ok(true)
2102
15.8k
        })?;
2103
15.8k
        Ok(ret)
2104
15.8k
    }
2105
2106
5.67k
    fn arbitrary_data(&mut self, u: &mut Unstructured) -> Result<()> {
2107
5.67k
        // With bulk-memory we can generate passive data, otherwise if there are
2108
5.67k
        // no memories we can't generate any data.
2109
5.67k
        let memories = self.memories.len() as u32;
2110
5.67k
        if memories == 0 && !self.config.bulk_memory_enabled {
2111
3.92k
            return Ok(());
2112
1.74k
        }
2113
1.74k
        let disallow_traps = self.config.disallow_traps;
2114
1.74k
        let mut choices32: Vec<Box<dyn Fn(&mut Unstructured, u64, usize) -> Result<Offset>>> =
2115
1.74k
            vec![];
2116
1.74k
        choices32.push(Box::new(|u, min_size, data_len| {
2117
414
            let min = u32::try_from(min_size.saturating_mul(64 * 1024))
2118
414
                .unwrap_or(u32::MAX)
2119
414
                .into();
2120
414
            let max = if disallow_traps { min } else { u32::MAX.into() };
2121
            Ok(Offset::Const32(
2122
414
                arbitrary_offset(u, min, max, data_len)? as i32
2123
            ))
2124
1.74k
        }));
2125
1.74k
        let mut choices64: Vec<Box<dyn Fn(&mut Unstructured, u64, usize) -> Result<Offset>>> =
2126
1.74k
            vec![];
2127
1.74k
        choices64.push(Box::new(|u, min_size, data_len| {
2128
0
            let min = min_size.saturating_mul(64 * 1024);
2129
0
            let max = if disallow_traps { min } else { u64::MAX };
2130
            Ok(Offset::Const64(
2131
0
                arbitrary_offset(u, min, max, data_len)? as i64
2132
            ))
2133
1.74k
        }));
2134
1.74k
        if !self.config.disallow_traps {
2135
1.74k
            for i in self.globals_for_const_expr(ValType::I32) {
2136
362
                choices32.push(Box::new(move |_, _, _| Ok(Offset::Global(i))));
2137
212
            }
2138
1.74k
            for i in self.globals_for_const_expr(ValType::I64) {
2139
167
                choices64.push(Box::new(move |_, _, _| Ok(Offset::Global(i))));
2140
167
            }
2141
0
        }
2142
2143
        // Build a list of candidate memories that we'll add data initializers
2144
        // for. If a memory doesn't have an initial size then any initializers
2145
        // for that memory will trap instantiation, which isn't too
2146
        // interesting. Try to make this happen less often by making it less
2147
        // likely that a memory with 0 size will have a data segment.
2148
1.74k
        let mut memories = Vec::new();
2149
1.74k
        for (i, mem) in self.memories.iter().enumerate() {
2150
1.74k
            if mem.minimum > 0 || u.int_in_range(0..=CHANCE_SEGMENT_ON_EMPTY)? == 0 {
2151
1.35k
                memories.push(i as u32);
2152
1.35k
            }
2153
        }
2154
2155
        // With memories we can generate data segments, and with bulk memory we
2156
        // can generate passive segments. Without these though we can't create
2157
        // a valid module with data segments.
2158
1.74k
        if memories.is_empty() && !self.config.bulk_memory_enabled {
2159
396
            return Ok(());
2160
1.35k
        }
2161
1.35k
2162
1.35k
        arbitrary_loop(
2163
1.35k
            u,
2164
1.35k
            self.config.min_data_segments,
2165
1.35k
            self.config.max_data_segments,
2166
1.35k
            |u| {
2167
776
                let mut init: Vec<u8> = u.arbitrary()?;
2168
2169
                // Passive data can only be generated if bulk memory is enabled.
2170
                // Otherwise if there are no memories we *only* generate passive
2171
                // data. Finally if all conditions are met we use an input byte to
2172
                // determine if it should be passive or active.
2173
776
                let kind =
2174
776
                    if self.config.bulk_memory_enabled && (memories.is_empty() || u.arbitrary()?) {
2175
0
                        DataSegmentKind::Passive
2176
                    } else {
2177
776
                        let memory_index = *u.choose(&memories)?;
2178
776
                        let mem = &self.memories[memory_index as usize];
2179
776
                        let f = if mem.memory64 {
2180
0
                            u.choose(&choices64)?
2181
                        } else {
2182
776
                            u.choose(&choices32)?
2183
                        };
2184
776
                        let mut offset = f(u, mem.minimum, init.len())?;
2185
2186
                        // If traps are disallowed then truncate the size of the
2187
                        // data segment to the minimum size of memory to guarantee
2188
                        // it will fit. Afterwards ensure that the offset of the
2189
                        // data segment is in-bounds by clamping it to the
2190
776
                        if self.config.disallow_traps {
2191
0
                            let max_size = (u64::MAX / 64 / 1024).min(mem.minimum) * 64 * 1024;
2192
0
                            init.truncate(max_size as usize);
2193
0
                            let max_offset = max_size - init.len() as u64;
2194
0
                            match &mut offset {
2195
0
                                Offset::Const32(x) => {
2196
0
                                    *x = (*x as u64).min(max_offset) as i32;
2197
0
                                }
2198
0
                                Offset::Const64(x) => {
2199
0
                                    *x = (*x as u64).min(max_offset) as i64;
2200
0
                                }
2201
0
                                Offset::Global(_) => unreachable!(),
2202
                            }
2203
776
                        }
2204
776
                        DataSegmentKind::Active {
2205
776
                            offset,
2206
776
                            memory_index,
2207
776
                        }
2208
                    };
2209
776
                self.data.push(DataSegment { kind, init });
2210
776
                Ok(true)
2211
1.35k
            },
2212
1.35k
        )
2213
5.67k
    }
2214
2215
6.68k
    fn params_results(&self, ty: &BlockType) -> (Vec<ValType>, Vec<ValType>) {
2216
6.68k
        match ty {
2217
3.06k
            BlockType::Empty => (vec![], vec![]),
2218
1.66k
            BlockType::Result(t) => (vec![], vec![*t]),
2219
1.95k
            BlockType::FunctionType(ty) => {
2220
1.95k
                let ty = self.func_type(*ty);
2221
1.95k
                (ty.params.to_vec(), ty.results.to_vec())
2222
            }
2223
        }
2224
6.68k
    }
2225
2226
    /// Returns an iterator of all globals which can be used in constant
2227
    /// expressions for a value of type `ty` specified.
2228
17.3k
    fn globals_for_const_expr(&self, ty: ValType) -> impl Iterator<Item = u32> + '_ {
2229
17.3k
        // Before the GC proposal only imported globals could be referenced, but
2230
17.3k
        // the GC proposal relaxed this feature to allow any global.
2231
17.3k
        let num_imported_globals = self.globals.len() - self.defined_globals.len();
2232
17.3k
        let max_global = if self.config.gc_enabled {
2233
0
            self.globals.len()
2234
        } else {
2235
17.3k
            num_imported_globals
2236
        };
2237
2238
17.3k
        self.globals[..max_global]
2239
17.3k
            .iter()
2240
17.3k
            .enumerate()
2241
17.3k
            .filter_map(move |(i, g)| {
2242
9.00k
                // Mutable globals cannot participate in constant expressions,
2243
9.00k
                // but otherwise so long as the global is a subtype of the
2244
9.00k
                // desired type it's a candidate.
2245
9.00k
                if !g.mutable && self.val_type_is_sub_type(g.val_type, ty) {
2246
1.81k
                    Some(i as u32)
2247
                } else {
2248
7.18k
                    None
2249
                }
2250
17.3k
            })
2251
17.3k
    }
2252
2253
5.67k
    fn compute_interesting_values(&mut self) {
2254
5.67k
        debug_assert!(self.interesting_values32.is_empty());
2255
5.67k
        debug_assert!(self.interesting_values64.is_empty());
2256
2257
5.67k
        let mut interesting_values32 = HashSet::new();
2258
5.67k
        let mut interesting_values64 = HashSet::new();
2259
5.67k
2260
1.68M
        let mut interesting = |val: u64| {
2261
1.68M
            interesting_values32.insert(val as u32);
2262
1.68M
            interesting_values64.insert(val);
2263
1.68M
        };
2264
2265
        // Zero is always interesting.
2266
5.67k
        interesting(0);
2267
5.67k
2268
5.67k
        // Max values are always interesting.
2269
5.67k
        interesting(u8::MAX as _);
2270
5.67k
        interesting(u16::MAX as _);
2271
5.67k
        interesting(u32::MAX as _);
2272
5.67k
        interesting(u64::MAX);
2273
5.67k
2274
5.67k
        // Min values are always interesting.
2275
5.67k
        interesting(i8::MIN as _);
2276
5.67k
        interesting(i16::MIN as _);
2277
5.67k
        interesting(i32::MIN as _);
2278
5.67k
        interesting(i64::MIN as _);
2279
2280
368k
        for i in 0..64 {
2281
363k
            // Powers of two.
2282
363k
            interesting(1 << i);
2283
363k
2284
363k
            // Inverted powers of two.
2285
363k
            interesting(!(1 << i));
2286
363k
2287
363k
            // Powers of two minus one, AKA high bits unset and low bits set.
2288
363k
            interesting((1 << i) - 1);
2289
363k
2290
363k
            // Negative powers of two, AKA high bits set and low bits unset.
2291
363k
            interesting(((1_i64 << 63) >> i) as _);
2292
363k
        }
2293
2294
        // Some repeating bit patterns.
2295
28.3k
        for pattern in [0b01010101, 0b00010001, 0b00010001, 0b00000001] {
2296
45.3k
            for b in [pattern, !pattern] {
2297
45.3k
                interesting(u64::from_ne_bytes([b, b, b, b, b, b, b, b]));
2298
45.3k
            }
2299
        }
2300
2301
        // Interesting float values.
2302
56.7k
        let mut interesting_f64 = |x: f64| interesting(x.to_bits());
2303
5.67k
        interesting_f64(0.0);
2304
5.67k
        interesting_f64(-0.0);
2305
5.67k
        interesting_f64(f64::INFINITY);
2306
5.67k
        interesting_f64(f64::NEG_INFINITY);
2307
5.67k
        interesting_f64(f64::EPSILON);
2308
5.67k
        interesting_f64(-f64::EPSILON);
2309
5.67k
        interesting_f64(f64::MIN);
2310
5.67k
        interesting_f64(f64::MIN_POSITIVE);
2311
5.67k
        interesting_f64(f64::MAX);
2312
5.67k
        interesting_f64(f64::NAN);
2313
56.7k
        let mut interesting_f32 = |x: f32| interesting(x.to_bits() as _);
2314
5.67k
        interesting_f32(0.0);
2315
5.67k
        interesting_f32(-0.0);
2316
5.67k
        interesting_f32(f32::INFINITY);
2317
5.67k
        interesting_f32(f32::NEG_INFINITY);
2318
5.67k
        interesting_f32(f32::EPSILON);
2319
5.67k
        interesting_f32(-f32::EPSILON);
2320
5.67k
        interesting_f32(f32::MIN);
2321
5.67k
        interesting_f32(f32::MIN_POSITIVE);
2322
5.67k
        interesting_f32(f32::MAX);
2323
5.67k
        interesting_f32(f32::NAN);
2324
2325
        // Interesting values related to table bounds.
2326
5.67k
        for t in self.tables.iter() {
2327
1.32k
            interesting(t.minimum as _);
2328
1.32k
            if let Some(x) = t.minimum.checked_add(1) {
2329
1.32k
                interesting(x as _);
2330
1.32k
            }
2331
2332
1.32k
            if let Some(x) = t.maximum {
2333
561
                interesting(x as _);
2334
561
                if let Some(y) = x.checked_add(1) {
2335
561
                    interesting(y as _);
2336
561
                }
2337
766
            }
2338
        }
2339
2340
        // Interesting values related to memory bounds.
2341
5.67k
        for m in self.memories.iter() {
2342
1.74k
            let min = m.minimum.saturating_mul(crate::page_size(m).into());
2343
1.74k
            interesting(min);
2344
10.4k
            for i in 0..5 {
2345
8.74k
                if let Some(x) = min.checked_add(1 << i) {
2346
8.74k
                    interesting(x);
2347
8.74k
                }
2348
8.74k
                if let Some(x) = min.checked_sub(1 << i) {
2349
5.24k
                    interesting(x);
2350
5.24k
                }
2351
            }
2352
2353
1.74k
            if let Some(max) = m.maximum {
2354
774
                let max = max.saturating_mul(crate::page_size(m).into());
2355
774
                interesting(max);
2356
4.64k
                for i in 0..5 {
2357
3.87k
                    if let Some(x) = max.checked_add(1 << i) {
2358
3.87k
                        interesting(x);
2359
3.87k
                    }
2360
3.87k
                    if let Some(x) = max.checked_sub(1 << i) {
2361
3.83k
                        interesting(x);
2362
3.83k
                    }
2363
                }
2364
974
            }
2365
        }
2366
2367
5.67k
        self.interesting_values32.extend(interesting_values32);
2368
5.67k
        self.interesting_values64.extend(interesting_values64);
2369
5.67k
2370
5.67k
        // Sort for determinism.
2371
5.67k
        self.interesting_values32.sort();
2372
5.67k
        self.interesting_values64.sort();
2373
5.67k
    }
2374
2375
12.3k
    fn arbitrary_const_instruction(
2376
12.3k
        &self,
2377
12.3k
        ty: ValType,
2378
12.3k
        u: &mut Unstructured<'_>,
2379
12.3k
    ) -> Result<Instruction> {
2380
12.3k
        debug_assert!(self.interesting_values32.len() > 0);
2381
12.3k
        debug_assert!(self.interesting_values64.len() > 0);
2382
12.3k
        match ty {
2383
4.51k
            ValType::I32 => Ok(Instruction::I32Const(if u.arbitrary()? {
2384
2.41k
                *u.choose(&self.interesting_values32)? as i32
2385
            } else {
2386
2.10k
                u.arbitrary()?
2387
            })),
2388
2.72k
            ValType::I64 => Ok(Instruction::I64Const(if u.arbitrary()? {
2389
1.61k
                *u.choose(&self.interesting_values64)? as i64
2390
            } else {
2391
1.11k
                u.arbitrary()?
2392
            })),
2393
2.92k
            ValType::F32 => Ok(Instruction::F32Const(if u.arbitrary()? {
2394
1.56k
                f32::from_bits(*u.choose(&self.interesting_values32)?)
2395
            } else {
2396
1.35k
                u.arbitrary()?
2397
            })),
2398
2.20k
            ValType::F64 => Ok(Instruction::F64Const(if u.arbitrary()? {
2399
1.32k
                f64::from_bits(*u.choose(&self.interesting_values64)?)
2400
            } else {
2401
884
                u.arbitrary()?
2402
            })),
2403
0
            ValType::V128 => Ok(Instruction::V128Const(if u.arbitrary()? {
2404
0
                let upper = (*u.choose(&self.interesting_values64)? as i128) << 64;
2405
0
                let lower = *u.choose(&self.interesting_values64)? as i128;
2406
0
                upper | lower
2407
            } else {
2408
0
                u.arbitrary()?
2409
            })),
2410
0
            ValType::Ref(ty) => {
2411
0
                assert!(ty.nullable);
2412
0
                Ok(Instruction::RefNull(ty.heap_type))
2413
            }
2414
        }
2415
12.3k
    }
2416
}
2417
2418
3.07k
pub(crate) fn arbitrary_limits64(
2419
3.07k
    u: &mut Unstructured,
2420
3.07k
    min_minimum: Option<u64>,
2421
3.07k
    max_minimum: u64,
2422
3.07k
    max_required: bool,
2423
3.07k
    max_inbounds: u64,
2424
3.07k
) -> Result<(u64, Option<u64>)> {
2425
3.07k
    let min = gradually_grow(u, min_minimum.unwrap_or(0), max_inbounds, max_minimum)?;
2426
3.07k
    let max = if max_required || u.arbitrary().unwrap_or(false) {
2427
1.33k
        Some(u.int_in_range(min..=max_minimum)?)
2428
    } else {
2429
1.74k
        None
2430
    };
2431
3.07k
    Ok((min, max))
2432
3.07k
}
2433
2434
5.67k
pub(crate) fn configured_valtypes(config: &Config) -> Vec<ValType> {
2435
5.67k
    let mut valtypes = Vec::with_capacity(25);
2436
5.67k
    valtypes.push(ValType::I32);
2437
5.67k
    valtypes.push(ValType::I64);
2438
5.67k
    valtypes.push(ValType::F32);
2439
5.67k
    valtypes.push(ValType::F64);
2440
5.67k
    if config.simd_enabled {
2441
0
        valtypes.push(ValType::V128);
2442
5.67k
    }
2443
5.67k
    if config.gc_enabled {
2444
0
        for nullable in [
2445
0
            // TODO: For now, only create allow nullable reference
2446
0
            // types. Eventually we should support non-nullable reference types,
2447
0
            // but this means that we will also need to recognize when it is
2448
0
            // impossible to create an instance of the reference (eg `(ref
2449
0
            // nofunc)` has no instances, and self-referential types that
2450
0
            // contain a non-null self-reference are also impossible to create).
2451
0
            true,
2452
0
        ] {
2453
0
            for heap_type in [
2454
0
                HeapType::Any,
2455
0
                HeapType::Eq,
2456
0
                HeapType::I31,
2457
0
                HeapType::Array,
2458
0
                HeapType::Struct,
2459
0
                HeapType::None,
2460
0
                HeapType::Func,
2461
0
                HeapType::NoFunc,
2462
0
                HeapType::Extern,
2463
0
                HeapType::NoExtern,
2464
0
            ] {
2465
0
                valtypes.push(ValType::Ref(RefType {
2466
0
                    nullable,
2467
0
                    heap_type,
2468
0
                }));
2469
0
            }
2470
        }
2471
5.67k
    } else if config.reference_types_enabled {
2472
0
        valtypes.push(ValType::EXTERNREF);
2473
0
        valtypes.push(ValType::FUNCREF);
2474
5.67k
    }
2475
5.67k
    valtypes
2476
5.67k
}
2477
2478
1.32k
pub(crate) fn arbitrary_table_type(
2479
1.32k
    u: &mut Unstructured,
2480
1.32k
    config: &Config,
2481
1.32k
    module: Option<&Module>,
2482
1.32k
) -> Result<TableType> {
2483
1.32k
    let table64 = config.memory64_enabled && u.arbitrary()?;
2484
    // We don't want to generate tables that are too large on average, so
2485
    // keep the "inbounds" limit here a bit smaller.
2486
1.32k
    let max_inbounds = 10_000;
2487
1.32k
    let min_elements = if config.disallow_traps { Some(1) } else { None };
2488
1.32k
    let max_elements = min_elements.unwrap_or(0).max(config.max_table_elements);
2489
1.32k
    let (minimum, maximum) = arbitrary_limits64(
2490
1.32k
        u,
2491
1.32k
        min_elements,
2492
1.32k
        max_elements,
2493
1.32k
        config.table_max_size_required,
2494
1.32k
        max_inbounds.min(max_elements),
2495
1.32k
    )?;
2496
1.32k
    if config.disallow_traps {
2497
0
        assert!(minimum > 0);
2498
1.32k
    }
2499
1.32k
    let element_type = match module {
2500
1.32k
        Some(module) => module.arbitrary_ref_type(u)?,
2501
0
        None => RefType::FUNCREF,
2502
    };
2503
1.32k
    Ok(TableType {
2504
1.32k
        element_type,
2505
1.32k
        minimum,
2506
1.32k
        maximum,
2507
1.32k
        table64,
2508
1.32k
    })
2509
1.32k
}
2510
2511
1.74k
pub(crate) fn arbitrary_memtype(u: &mut Unstructured, config: &Config) -> Result<MemoryType> {
2512
    // When threads are enabled, we only want to generate shared memories about
2513
    // 25% of the time.
2514
1.74k
    let shared = config.threads_enabled && u.ratio(1, 4)?;
2515
    // We want to favor memories <= 1gb in size, allocate at most 16k pages,
2516
    // depending on the maximum number of memories.
2517
1.74k
    let memory64 = config.memory64_enabled && u.arbitrary()?;
2518
1.74k
    let page_size = if config.custom_page_sizes_enabled && u.arbitrary()? {
2519
0
        Some(1 << u.int_in_range(0..=16)?)
2520
    } else {
2521
1.74k
        None
2522
    };
2523
1.74k
    let max_inbounds = 16 * 1024 / u64::try_from(config.max_memories).unwrap();
2524
1.74k
    let min_pages = if config.disallow_traps { Some(1) } else { None };
2525
1.74k
    let max_pages = min_pages.unwrap_or(0).max(if memory64 {
2526
0
        config.max_memory64_pages
2527
    } else {
2528
1.74k
        config.max_memory32_pages
2529
    });
2530
1.74k
    let (minimum, maximum) = arbitrary_limits64(
2531
1.74k
        u,
2532
1.74k
        min_pages,
2533
1.74k
        max_pages,
2534
1.74k
        config.memory_max_size_required || shared,
2535
1.74k
        max_inbounds.min(max_pages),
2536
0
    )?;
2537
1.74k
    Ok(MemoryType {
2538
1.74k
        minimum,
2539
1.74k
        maximum,
2540
1.74k
        memory64,
2541
1.74k
        shared,
2542
1.74k
        page_size_log2: page_size,
2543
1.74k
    })
2544
1.74k
}
2545
2546
0
pub(crate) fn arbitrary_tag_type(
2547
0
    u: &mut Unstructured,
2548
0
    candidate_func_types: &[u32],
2549
0
    get_func_type: impl FnOnce(u32) -> Rc<FuncType>,
2550
0
) -> Result<TagType> {
2551
0
    let max = candidate_func_types.len() - 1;
2552
0
    let ty = candidate_func_types[u.int_in_range(0..=max)?];
2553
0
    Ok(TagType {
2554
0
        func_type_idx: ty,
2555
0
        func_type: get_func_type(ty),
2556
0
    })
2557
0
}
Unexecuted instantiation: _RINvNtCs4eJdYXiOSk9_10wasm_smith4core18arbitrary_tag_typeNCNCNvMs4_NtB4_9componentNtB13_16ComponentBuilder26arbitrary_core_entity_types2_0s0_0EB4_
Unexecuted instantiation: _RINvNtCs4eJdYXiOSk9_10wasm_smith4core18arbitrary_tag_typeNCNvMs3_B2_NtB2_6Module18arbitrary_tag_type0EB4_
2558
2559
/// This function generates a number between `min` and `max`, favoring values
2560
/// between `min` and `max_inbounds`.
2561
///
2562
/// The thinking behind this function is that it's used for things like offsets
2563
/// and minimum sizes which, when very large, can trivially make the wasm oom or
2564
/// abort with a trap. This isn't the most interesting thing to do so it tries
2565
/// to favor numbers in the `min..max_inbounds` range to avoid immediate ooms.
2566
4.64k
fn gradually_grow(u: &mut Unstructured, min: u64, max_inbounds: u64, max: u64) -> Result<u64> {
2567
4.64k
    if min == max {
2568
0
        return Ok(min);
2569
4.64k
    }
2570
4.64k
    let min = min as f64;
2571
4.64k
    let max = max as f64;
2572
4.64k
    let max_inbounds = max_inbounds as f64;
2573
4.64k
    let x = u.arbitrary::<u32>()?;
2574
4.64k
    let x = f64::from(x);
2575
4.64k
    let x = map_custom(
2576
4.64k
        x,
2577
4.64k
        f64::from(u32::MIN)..f64::from(u32::MAX),
2578
4.64k
        min..max_inbounds,
2579
4.64k
        min..max,
2580
4.64k
    );
2581
4.64k
    return Ok(x.round() as u64);
2582
2583
    /// Map a value from within the input range to the output range(s).
2584
    ///
2585
    /// This will first map the input range into the `0..1` input range, and
2586
    /// then depending on the value it will either map it exponentially
2587
    /// (favoring small values) into the `output_inbounds` range or it will map
2588
    /// it into the `output` range.
2589
4.64k
    fn map_custom(
2590
4.64k
        value: f64,
2591
4.64k
        input: Range<f64>,
2592
4.64k
        output_inbounds: Range<f64>,
2593
4.64k
        output: Range<f64>,
2594
4.64k
    ) -> f64 {
2595
4.64k
        assert!(!value.is_nan(), "{}", value);
2596
4.64k
        assert!(value.is_finite(), "{}", value);
2597
4.64k
        assert!(input.start < input.end, "{} < {}", input.start, input.end);
2598
4.64k
        assert!(
2599
4.64k
            output.start < output.end,
2600
0
            "{} < {}",
2601
            output.start,
2602
            output.end
2603
        );
2604
4.64k
        assert!(value >= input.start, "{} >= {}", value, input.start);
2605
4.64k
        assert!(value <= input.end, "{} <= {}", value, input.end);
2606
4.64k
        assert!(
2607
4.64k
            output.start <= output_inbounds.start,
2608
0
            "{} <= {}",
2609
            output.start,
2610
            output_inbounds.start
2611
        );
2612
4.64k
        assert!(
2613
4.64k
            output_inbounds.end <= output.end,
2614
0
            "{} <= {}",
2615
            output_inbounds.end,
2616
            output.end
2617
        );
2618
2619
4.64k
        let x = map_linear(value, input, 0.0..1.0);
2620
4.64k
        let result = if x < PCT_INBOUNDS {
2621
3.68k
            if output_inbounds.start == output_inbounds.end {
2622
418
                output_inbounds.start
2623
            } else {
2624
3.26k
                let unscaled = x * x * x * x * x * x;
2625
3.26k
                map_linear(unscaled, 0.0..1.0, output_inbounds)
2626
            }
2627
        } else {
2628
965
            map_linear(x, 0.0..1.0, output.clone())
2629
        };
2630
2631
4.64k
        assert!(result >= output.start, "{} >= {}", result, output.start);
2632
4.64k
        assert!(result <= output.end, "{} <= {}", result, output.end);
2633
4.64k
        result
2634
4.64k
    }
2635
2636
    /// Map a value from within the input range linearly to the output range.
2637
    ///
2638
    /// For example, mapping `0.5` from the input range `0.0..1.0` to the output
2639
    /// range `1.0..3.0` produces `2.0`.
2640
8.87k
    fn map_linear(
2641
8.87k
        value: f64,
2642
8.87k
        Range {
2643
8.87k
            start: in_low,
2644
8.87k
            end: in_high,
2645
8.87k
        }: Range<f64>,
2646
8.87k
        Range {
2647
8.87k
            start: out_low,
2648
8.87k
            end: out_high,
2649
8.87k
        }: Range<f64>,
2650
8.87k
    ) -> f64 {
2651
8.87k
        assert!(!value.is_nan(), "{}", value);
2652
8.87k
        assert!(value.is_finite(), "{}", value);
2653
8.87k
        assert!(in_low < in_high, "{} < {}", in_low, in_high);
2654
8.87k
        assert!(out_low < out_high, "{} < {}", out_low, out_high);
2655
8.87k
        assert!(value >= in_low, "{} >= {}", value, in_low);
2656
8.87k
        assert!(value <= in_high, "{} <= {}", value, in_high);
2657
2658
8.87k
        let dividend = out_high - out_low;
2659
8.87k
        let divisor = in_high - in_low;
2660
8.87k
        let slope = dividend / divisor;
2661
8.87k
        let result = out_low + (slope * (value - in_low));
2662
8.87k
2663
8.87k
        assert!(result >= out_low, "{} >= {}", result, out_low);
2664
8.87k
        assert!(result <= out_high, "{} <= {}", result, out_high);
2665
8.87k
        result
2666
8.87k
    }
2667
4.64k
}
2668
2669
/// Selects a reasonable offset for an element or data segment. This favors
2670
/// having the segment being in-bounds, but it may still generate
2671
/// any offset.
2672
1.61k
fn arbitrary_offset(
2673
1.61k
    u: &mut Unstructured,
2674
1.61k
    limit_min: u64,
2675
1.61k
    limit_max: u64,
2676
1.61k
    segment_size: usize,
2677
1.61k
) -> Result<u64> {
2678
1.61k
    let size = u64::try_from(segment_size).unwrap();
2679
1.61k
2680
1.61k
    // If the segment is too big for the whole memory, just give it any
2681
1.61k
    // offset.
2682
1.61k
    if size > limit_min {
2683
47
        u.int_in_range(0..=limit_max)
2684
    } else {
2685
1.57k
        gradually_grow(u, 0, limit_min - size, limit_max)
2686
    }
2687
1.61k
}
2688
2689
4.32k
fn unique_import_strings(max_size: usize, u: &mut Unstructured) -> Result<(String, String)> {
2690
4.32k
    let module = limited_string(max_size, u)?;
2691
4.32k
    let field = limited_string(max_size, u)?;
2692
4.32k
    Ok((module, field))
2693
4.32k
}
2694
2695
0
fn arbitrary_vec_u8(u: &mut Unstructured) -> Result<Vec<u8>> {
2696
0
    let size = u.arbitrary_len::<u8>()?;
2697
0
    Ok(u.bytes(size)?.to_vec())
2698
0
}
2699
2700
impl EntityType {
2701
33.5k
    fn size(&self) -> u32 {
2702
33.5k
        match self {
2703
            EntityType::Tag(_)
2704
            | EntityType::Global(_)
2705
            | EntityType::Table(_)
2706
16.6k
            | EntityType::Memory(_) => 1,
2707
16.8k
            EntityType::Func(_, ty) => 1 + (ty.params.len() + ty.results.len()) as u32,
2708
        }
2709
33.5k
    }
2710
}
2711
2712
// A helper structure used when generating module/instance types to limit the
2713
// amount of each kind of import created.
2714
#[derive(Default, Clone, Copy, PartialEq)]
2715
struct Entities {
2716
    globals: usize,
2717
    memories: usize,
2718
    tables: usize,
2719
    funcs: usize,
2720
    tags: usize,
2721
}
2722
2723
/// A container for the kinds of instructions that wasm-smith is allowed to
2724
/// emit.
2725
///
2726
/// # Example
2727
///
2728
/// ```
2729
/// # use wasm_smith::{InstructionKinds, InstructionKind};
2730
/// let kinds = InstructionKinds::new(&[InstructionKind::Numeric, InstructionKind::Memory]);
2731
/// assert!(kinds.contains(InstructionKind::Memory));
2732
/// ```
2733
#[derive(Clone, Copy, Debug, Default)]
2734
#[cfg_attr(feature = "serde_derive", derive(serde_derive::Deserialize))]
2735
pub struct InstructionKinds(pub(crate) FlagSet<InstructionKind>);
2736
2737
impl InstructionKinds {
2738
    /// Create a new container.
2739
0
    pub fn new(kinds: &[InstructionKind]) -> Self {
2740
0
        Self(kinds.iter().fold(FlagSet::default(), |ks, k| ks | *k))
2741
0
    }
2742
2743
    /// Include all [InstructionKind]s.
2744
5.67k
    pub fn all() -> Self {
2745
5.67k
        Self(FlagSet::full())
2746
5.67k
    }
2747
2748
    /// Include no [InstructionKind]s.
2749
0
    pub fn none() -> Self {
2750
0
        Self(FlagSet::default())
2751
0
    }
2752
2753
    /// Check if the [InstructionKind] is contained in this set.
2754
    #[inline]
2755
2.51M
    pub fn contains(&self, kind: InstructionKind) -> bool {
2756
2.51M
        self.0.contains(kind)
2757
2.51M
    }
2758
}
2759
2760
flags! {
2761
    /// Enumerate the categories of instructions defined in the [WebAssembly
2762
    /// specification](https://webassembly.github.io/spec/core/syntax/instructions.html).
2763
    #[allow(missing_docs)]
2764
    #[cfg_attr(feature = "_internal_cli", derive(serde_derive::Deserialize))]
2765
    pub enum InstructionKind: u16 {
2766
        Numeric,
2767
        Vector,
2768
        Reference,
2769
        Parametric,
2770
        Variable,
2771
        Table,
2772
        Memory,
2773
        Control,
2774
        Aggregate,
2775
    }
2776
}
2777
2778
impl FromStr for InstructionKinds {
2779
    type Err = String;
2780
0
    fn from_str(s: &str) -> std::prelude::v1::Result<Self, Self::Err> {
2781
0
        let mut kinds = vec![];
2782
0
        for part in s.split(",") {
2783
0
            let kind = InstructionKind::from_str(part)?;
2784
0
            kinds.push(kind);
2785
        }
2786
0
        Ok(InstructionKinds::new(&kinds))
2787
0
    }
2788
}
2789
2790
impl FromStr for InstructionKind {
2791
    type Err = String;
2792
0
    fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
2793
0
        match s.to_lowercase().as_str() {
2794
0
            "numeric" => Ok(InstructionKind::Numeric),
2795
0
            "vector" => Ok(InstructionKind::Vector),
2796
0
            "reference" => Ok(InstructionKind::Reference),
2797
0
            "parametric" => Ok(InstructionKind::Parametric),
2798
0
            "variable" => Ok(InstructionKind::Variable),
2799
0
            "table" => Ok(InstructionKind::Table),
2800
0
            "memory" => Ok(InstructionKind::Memory),
2801
0
            "control" => Ok(InstructionKind::Control),
2802
0
            _ => Err(format!("unknown instruction kind: {}", s)),
2803
        }
2804
0
    }
2805
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/core/code_builder.rs
Line
Count
Source (jump to first uncovered line)
1
use super::{
2
    CompositeType, Elements, FuncType, Instruction, InstructionKind::*, InstructionKinds, Module,
3
    ValType,
4
};
5
use crate::{unique_string, MemoryOffsetChoices};
6
use arbitrary::{Result, Unstructured};
7
use std::collections::{BTreeMap, BTreeSet};
8
use std::rc::Rc;
9
use wasm_encoder::{
10
    ArrayType, BlockType, Catch, ConstExpr, ExportKind, FieldType, GlobalType, HeapType, MemArg,
11
    RefType, StorageType, StructType,
12
};
13
mod no_traps;
14
15
macro_rules! instructions {
16
    (
17
        $(
18
            ($predicate:expr, $generator_fn:ident, $instruction_kind:ident $(, $cost:tt)?),
19
        )*
20
    ) => {
21
        static NUM_OPTIONS: usize = instructions!(
22
            @count;
23
            $( $generator_fn )*
24
        );
25
26
81.2k
        fn choose_instruction(
27
81.2k
            u: &mut Unstructured<'_>,
28
81.2k
            module: &Module,
29
81.2k
            allowed_instructions: InstructionKinds,
30
81.2k
            builder: &mut CodeBuilder,
31
81.2k
        ) -> Option<
32
81.2k
            fn(&mut Unstructured<'_>, &Module, &mut CodeBuilder, &mut Vec<Instruction>) -> Result<()>
33
81.2k
        > {
34
81.2k
            builder.allocs.options.clear();
35
81.2k
            let mut cost = 0;
36
            // Unroll the loop that checks whether each instruction is valid in
37
            // the current context and, if it is valid, pushes it onto our
38
            // options. Unrolling this loops lets us avoid dynamic calls through
39
            // function pointers and, furthermore, each call site can be branch
40
            // predicted and even inlined. This saved us about 30% of time in
41
            // the `corpus` benchmark.
42
            $(
43
81.2k
                let predicate: Option<fn(&Module, &mut CodeBuilder) -> bool> = $predicate;
44
39.3M
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instruction0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
Unexecuted instantiation: _RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions_0B7_
Unexecuted instantiation: _RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions0_0B7_
Unexecuted instantiation: _RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1_0B7_
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions8_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions9_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsa_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsb_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsc_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsd_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionse_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsf_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsg_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsh_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsi_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsj_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsk_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsl_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsm_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsn_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionso_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsp_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsq_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsr_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionss_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionst_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsu_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsv_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsw_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsx_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsy_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsz_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsA_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsB_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsC_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsD_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsE_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsF_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsG_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsH_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsI_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsJ_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsK_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsL_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsM_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsN_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsO_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsP_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsQ_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsR_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsS_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsT_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsU_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsV_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
Unexecuted instantiation: _RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsW_0B7_
Unexecuted instantiation: _RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsX_0B7_
Unexecuted instantiation: _RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsY_0B7_
Unexecuted instantiation: _RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructionsZ_0B7_
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions10_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions11_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions12_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions13_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions14_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions15_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions16_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions17_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions18_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions19_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1a_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1b_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1c_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1d_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1e_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1f_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1g_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1h_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1i_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1j_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1k_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1l_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1m_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1n_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1o_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1p_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1r_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1s_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1t_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1u_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1v_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1w_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1x_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1A_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1B_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1C_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1D_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1E_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1F_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1G_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1H_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1I_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1J_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1K_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1L_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1M_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1N_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1O_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1P_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1Q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1R_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1S_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1T_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1U_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1V_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1W_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1X_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1Y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions1Z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions20_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions21_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions22_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions23_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions24_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions25_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions26_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions27_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions28_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions29_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2a_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2b_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2c_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2d_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2e_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2f_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2g_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2h_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2i_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2j_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2k_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2l_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2m_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2n_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2o_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2p_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2r_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2s_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2t_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2u_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2v_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2w_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2x_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2A_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2B_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2C_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2D_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2E_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2F_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2G_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2H_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2I_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2J_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2K_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2L_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2M_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2N_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2O_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2P_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2Q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2R_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2S_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2T_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2U_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2V_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2W_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2X_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2Y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions2Z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions30_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions31_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions32_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions33_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions34_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions35_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions36_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions37_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions38_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions39_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3a_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3b_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3c_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3d_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3e_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3f_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3g_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3h_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3i_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3j_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3k_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3l_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3m_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3n_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3o_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3p_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3r_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3s_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3t_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3u_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3v_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3w_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3x_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3A_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3B_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3C_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3D_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3E_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3F_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3G_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3H_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3I_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3J_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3K_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3L_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3M_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3N_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3O_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3P_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3Q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3R_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3S_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3T_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3U_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3V_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3W_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3X_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3Y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions3Z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions40_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions41_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions42_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions43_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions44_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions45_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions46_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions47_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions48_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions49_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4a_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4b_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4c_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4d_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4e_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4f_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4g_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4h_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4i_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4j_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4k_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4l_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4m_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4n_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4o_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4p_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4r_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4s_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4t_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4u_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4v_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4w_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4x_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4A_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4B_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4C_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4D_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4E_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4F_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4G_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4H_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4I_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4J_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4K_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4L_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4M_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4N_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4O_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4P_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4Q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4R_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4S_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4T_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4U_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4V_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4W_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4X_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4Y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions4Z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions50_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions51_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions52_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions53_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions54_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions55_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions56_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions57_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions58_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions59_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5a_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5b_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5c_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5d_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5e_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5f_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5g_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5h_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5i_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5j_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5k_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5l_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5m_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5n_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5o_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5p_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5r_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5s_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5t_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5u_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5v_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5w_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5x_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5A_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5B_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5C_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5D_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5E_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5F_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5G_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5H_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5I_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5J_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5K_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5L_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5M_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5N_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5O_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5P_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5Q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5R_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5S_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5T_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5U_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5V_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5W_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5X_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5Y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions5Z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions60_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions61_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions62_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions63_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions64_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions65_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions66_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions67_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions68_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions69_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6a_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6b_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6c_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6d_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6e_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6f_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6g_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6h_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6i_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6j_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6k_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6l_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6m_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6n_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6o_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6p_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6r_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6s_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6t_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6u_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6v_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6w_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6x_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6A_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6B_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6C_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6D_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6E_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6F_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6G_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6H_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6I_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6J_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6K_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6L_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6M_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6N_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6O_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6P_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6Q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6R_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6S_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6T_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6U_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6V_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6W_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6X_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6Y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions6Z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions70_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions71_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions72_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions73_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions74_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions75_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions76_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions77_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions78_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions79_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7a_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7b_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7c_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7d_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7e_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7f_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7g_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7h_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7i_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7j_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7k_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7l_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7m_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7n_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7o_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7p_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7r_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7s_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7t_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7u_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7v_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7w_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7x_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7y_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7z_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7A_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7B_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7C_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7D_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7E_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7F_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7G_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7H_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7I_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7J_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7K_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7L_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7M_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7N_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7O_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7P_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7Q_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7R_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
_RNCNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18choose_instructions7S_0B7_
Line
Count
Source
44
81.2k
                if predicate.map_or(true, |f| f(module, builder))
45
0
                    && allowed_instructions.contains($instruction_kind) {
46
0
                    builder.allocs.options.push(($generator_fn, cost));
47
66.0k
                    cost += 1000 $(- $cost)?;
48
81.2k
                }
49
            )*
50
51
            // If there aren't actually any candidate instructions due to
52
            // various filters in place then return `None` to indicate the
53
            // situation.
54
81.2k
            if cost == 0 {
55
0
                return None;
56
81.2k
            }
57
58
81.2k
            let i = u.int_in_range(0..=cost).ok()?;
59
81.2k
            let idx = builder
60
81.2k
                .allocs
61
81.2k
                .options
62
396k
                .binary_search_by_key(&i,|p| p.1)
63
81.2k
                .unwrap_or_else(|i| i - 1);
64
81.2k
            Some(builder.allocs.options[idx].0)
65
81.2k
        }
66
    };
67
68
    ( @count; ) => {
69
        0
70
    };
71
    ( @count; $x:ident $( $xs:ident )* ) => {
72
        1 + instructions!( @count; $( $xs )* )
73
    };
74
}
75
76
// The static set of options of instruction to generate that could be valid at
77
// some given time. One entry per Wasm instruction.
78
//
79
// Each entry is made up of up to three parts:
80
//
81
// 1. A predicate for whether this is a valid choice, if any. `None` means that
82
//    the choice is always applicable.
83
//
84
// 2. The function to generate the instruction, given that we've made this
85
//    choice.
86
//
87
// 3. The `InstructionKind` the instruction belongs to; this allows filtering
88
//    out instructions by category.
89
//
90
// 4. An optional number used to weight how often this instruction is chosen.
91
//    Higher numbers are less likely to be chosen, and number specified must be
92
//    less than 1000.
93
instructions! {
94
    // Control instructions.
95
    (Some(unreachable_valid), unreachable, Control, 990),
96
    (None, nop, Control, 800),
97
    (None, block, Control),
98
    (None, r#loop, Control),
99
    (Some(try_table_valid), try_table, Control),
100
    (Some(if_valid), r#if, Control),
101
    (Some(else_valid), r#else, Control),
102
    (Some(end_valid), end, Control),
103
    (Some(br_valid), br, Control),
104
    (Some(br_if_valid), br_if, Control),
105
    (Some(br_table_valid), br_table, Control),
106
    (Some(return_valid), r#return, Control, 900),
107
    (Some(call_valid), call, Control),
108
    (Some(call_ref_valid), call_ref, Control),
109
    (Some(call_indirect_valid), call_indirect, Control),
110
    (Some(return_call_valid), return_call, Control),
111
    (Some(return_call_ref_valid), return_call_ref, Control),
112
    (Some(return_call_indirect_valid), return_call_indirect, Control),
113
    (Some(throw_valid), throw, Control, 850),
114
    (Some(throw_ref_valid), throw_ref, Control, 850),
115
    (Some(br_on_null_valid), br_on_null, Control),
116
    (Some(br_on_non_null_valid), br_on_non_null, Control),
117
    (Some(br_on_cast_valid), br_on_cast, Control),
118
    (Some(br_on_cast_fail_valid), br_on_cast_fail, Control),
119
    // Parametric instructions.
120
    (Some(drop_valid), drop, Parametric, 990),
121
    (Some(select_valid), select, Parametric),
122
    // Variable instructions.
123
    (Some(local_get_valid), local_get, Variable),
124
    (Some(local_set_valid), local_set, Variable),
125
    (Some(local_set_valid), local_tee, Variable),
126
    (Some(global_get_valid), global_get, Variable),
127
    (Some(global_set_valid), global_set, Variable),
128
    // Memory instructions.
129
    (Some(have_memory_and_offset), i32_load, Memory),
130
    (Some(have_memory_and_offset), i64_load, Memory),
131
    (Some(have_memory_and_offset), f32_load, Memory),
132
    (Some(have_memory_and_offset), f64_load, Memory),
133
    (Some(have_memory_and_offset), i32_load_8_s, Memory),
134
    (Some(have_memory_and_offset), i32_load_8_u, Memory),
135
    (Some(have_memory_and_offset), i32_load_16_s, Memory),
136
    (Some(have_memory_and_offset), i32_load_16_u, Memory),
137
    (Some(have_memory_and_offset), i64_load_8_s, Memory),
138
    (Some(have_memory_and_offset), i64_load_16_s, Memory),
139
    (Some(have_memory_and_offset), i64_load_32_s, Memory),
140
    (Some(have_memory_and_offset), i64_load_8_u, Memory),
141
    (Some(have_memory_and_offset), i64_load_16_u, Memory),
142
    (Some(have_memory_and_offset), i64_load_32_u, Memory),
143
    (Some(i32_store_valid), i32_store, Memory),
144
    (Some(i64_store_valid), i64_store, Memory),
145
    (Some(f32_store_valid), f32_store, Memory),
146
    (Some(f64_store_valid), f64_store, Memory),
147
    (Some(i32_store_valid), i32_store_8, Memory),
148
    (Some(i32_store_valid), i32_store_16, Memory),
149
    (Some(i64_store_valid), i64_store_8, Memory),
150
    (Some(i64_store_valid), i64_store_16, Memory),
151
    (Some(i64_store_valid), i64_store_32, Memory),
152
    (Some(have_memory), memory_size, Memory),
153
    (Some(memory_grow_valid), memory_grow, Memory),
154
    (Some(memory_init_valid), memory_init, Memory),
155
    (Some(data_drop_valid), data_drop, Memory),
156
    (Some(memory_copy_valid), memory_copy, Memory),
157
    (Some(memory_fill_valid), memory_fill, Memory),
158
    // Numeric instructions.
159
    (None, i32_const, Numeric),
160
    (None, i64_const, Numeric),
161
    (None, f32_const, Numeric),
162
    (None, f64_const, Numeric),
163
    (Some(i32_on_stack), i32_eqz, Numeric),
164
    (Some(i32_i32_on_stack), i32_eq, Numeric),
165
    (Some(i32_i32_on_stack), i32_ne, Numeric),
166
    (Some(i32_i32_on_stack), i32_lt_s, Numeric),
167
    (Some(i32_i32_on_stack), i32_lt_u, Numeric),
168
    (Some(i32_i32_on_stack), i32_gt_s, Numeric),
169
    (Some(i32_i32_on_stack), i32_gt_u, Numeric),
170
    (Some(i32_i32_on_stack), i32_le_s, Numeric),
171
    (Some(i32_i32_on_stack), i32_le_u, Numeric),
172
    (Some(i32_i32_on_stack), i32_ge_s, Numeric),
173
    (Some(i32_i32_on_stack), i32_ge_u, Numeric),
174
    (Some(i64_on_stack), i64_eqz, Numeric),
175
    (Some(i64_i64_on_stack), i64_eq, Numeric),
176
    (Some(i64_i64_on_stack), i64_ne, Numeric),
177
    (Some(i64_i64_on_stack), i64_lt_s, Numeric),
178
    (Some(i64_i64_on_stack), i64_lt_u, Numeric),
179
    (Some(i64_i64_on_stack), i64_gt_s, Numeric),
180
    (Some(i64_i64_on_stack), i64_gt_u, Numeric),
181
    (Some(i64_i64_on_stack), i64_le_s, Numeric),
182
    (Some(i64_i64_on_stack), i64_le_u, Numeric),
183
    (Some(i64_i64_on_stack), i64_ge_s, Numeric),
184
    (Some(i64_i64_on_stack), i64_ge_u, Numeric),
185
    (Some(f32_f32_on_stack), f32_eq, Numeric),
186
    (Some(f32_f32_on_stack), f32_ne, Numeric),
187
    (Some(f32_f32_on_stack), f32_lt, Numeric),
188
    (Some(f32_f32_on_stack), f32_gt, Numeric),
189
    (Some(f32_f32_on_stack), f32_le, Numeric),
190
    (Some(f32_f32_on_stack), f32_ge, Numeric),
191
    (Some(f64_f64_on_stack), f64_eq, Numeric),
192
    (Some(f64_f64_on_stack), f64_ne, Numeric),
193
    (Some(f64_f64_on_stack), f64_lt, Numeric),
194
    (Some(f64_f64_on_stack), f64_gt, Numeric),
195
    (Some(f64_f64_on_stack), f64_le, Numeric),
196
    (Some(f64_f64_on_stack), f64_ge, Numeric),
197
    (Some(i32_on_stack), i32_clz, Numeric),
198
    (Some(i32_on_stack), i32_ctz, Numeric),
199
    (Some(i32_on_stack), i32_popcnt, Numeric),
200
    (Some(i32_i32_on_stack), i32_add, Numeric),
201
    (Some(i32_i32_on_stack), i32_sub, Numeric),
202
    (Some(i32_i32_on_stack), i32_mul, Numeric),
203
    (Some(i32_i32_on_stack), i32_div_s, Numeric),
204
    (Some(i32_i32_on_stack), i32_div_u, Numeric),
205
    (Some(i32_i32_on_stack), i32_rem_s, Numeric),
206
    (Some(i32_i32_on_stack), i32_rem_u, Numeric),
207
    (Some(i32_i32_on_stack), i32_and, Numeric),
208
    (Some(i32_i32_on_stack), i32_or, Numeric),
209
    (Some(i32_i32_on_stack), i32_xor, Numeric),
210
    (Some(i32_i32_on_stack), i32_shl, Numeric),
211
    (Some(i32_i32_on_stack), i32_shr_s, Numeric),
212
    (Some(i32_i32_on_stack), i32_shr_u, Numeric),
213
    (Some(i32_i32_on_stack), i32_rotl, Numeric),
214
    (Some(i32_i32_on_stack), i32_rotr, Numeric),
215
    (Some(i64_on_stack), i64_clz, Numeric),
216
    (Some(i64_on_stack), i64_ctz, Numeric),
217
    (Some(i64_on_stack), i64_popcnt, Numeric),
218
    (Some(i64_i64_on_stack), i64_add, Numeric),
219
    (Some(i64_i64_on_stack), i64_sub, Numeric),
220
    (Some(i64_i64_on_stack), i64_mul, Numeric),
221
    (Some(i64_i64_on_stack), i64_div_s, Numeric),
222
    (Some(i64_i64_on_stack), i64_div_u, Numeric),
223
    (Some(i64_i64_on_stack), i64_rem_s, Numeric),
224
    (Some(i64_i64_on_stack), i64_rem_u, Numeric),
225
    (Some(i64_i64_on_stack), i64_and, Numeric),
226
    (Some(i64_i64_on_stack), i64_or, Numeric),
227
    (Some(i64_i64_on_stack), i64_xor, Numeric),
228
    (Some(i64_i64_on_stack), i64_shl, Numeric),
229
    (Some(i64_i64_on_stack), i64_shr_s, Numeric),
230
    (Some(i64_i64_on_stack), i64_shr_u, Numeric),
231
    (Some(i64_i64_on_stack), i64_rotl, Numeric),
232
    (Some(i64_i64_on_stack), i64_rotr, Numeric),
233
    (Some(f32_on_stack), f32_abs, Numeric),
234
    (Some(f32_on_stack), f32_neg, Numeric),
235
    (Some(f32_on_stack), f32_ceil, Numeric),
236
    (Some(f32_on_stack), f32_floor, Numeric),
237
    (Some(f32_on_stack), f32_trunc, Numeric),
238
    (Some(f32_on_stack), f32_nearest, Numeric),
239
    (Some(f32_on_stack), f32_sqrt, Numeric),
240
    (Some(f32_f32_on_stack), f32_add, Numeric),
241
    (Some(f32_f32_on_stack), f32_sub, Numeric),
242
    (Some(f32_f32_on_stack), f32_mul, Numeric),
243
    (Some(f32_f32_on_stack), f32_div, Numeric),
244
    (Some(f32_f32_on_stack), f32_min, Numeric),
245
    (Some(f32_f32_on_stack), f32_max, Numeric),
246
    (Some(f32_f32_on_stack), f32_copysign, Numeric),
247
    (Some(f64_on_stack), f64_abs, Numeric),
248
    (Some(f64_on_stack), f64_neg, Numeric),
249
    (Some(f64_on_stack), f64_ceil, Numeric),
250
    (Some(f64_on_stack), f64_floor, Numeric),
251
    (Some(f64_on_stack), f64_trunc, Numeric),
252
    (Some(f64_on_stack), f64_nearest, Numeric),
253
    (Some(f64_on_stack), f64_sqrt, Numeric),
254
    (Some(f64_f64_on_stack), f64_add, Numeric),
255
    (Some(f64_f64_on_stack), f64_sub, Numeric),
256
    (Some(f64_f64_on_stack), f64_mul, Numeric),
257
    (Some(f64_f64_on_stack), f64_div, Numeric),
258
    (Some(f64_f64_on_stack), f64_min, Numeric),
259
    (Some(f64_f64_on_stack), f64_max, Numeric),
260
    (Some(f64_f64_on_stack), f64_copysign, Numeric),
261
    (Some(i64_on_stack), i32_wrap_i64, Numeric),
262
    (Some(f32_on_stack), i32_trunc_f32_s, Numeric),
263
    (Some(f32_on_stack), i32_trunc_f32_u, Numeric),
264
    (Some(f64_on_stack), i32_trunc_f64_s, Numeric),
265
    (Some(f64_on_stack), i32_trunc_f64_u, Numeric),
266
    (Some(i32_on_stack), i64_extend_i32_s, Numeric),
267
    (Some(i32_on_stack), i64_extend_i32_u, Numeric),
268
    (Some(f32_on_stack), i64_trunc_f32_s, Numeric),
269
    (Some(f32_on_stack), i64_trunc_f32_u, Numeric),
270
    (Some(f64_on_stack), i64_trunc_f64_s, Numeric),
271
    (Some(f64_on_stack), i64_trunc_f64_u, Numeric),
272
    (Some(i32_on_stack), f32_convert_i32_s, Numeric),
273
    (Some(i32_on_stack), f32_convert_i32_u, Numeric),
274
    (Some(i64_on_stack), f32_convert_i64_s, Numeric),
275
    (Some(i64_on_stack), f32_convert_i64_u, Numeric),
276
    (Some(f64_on_stack), f32_demote_f64, Numeric),
277
    (Some(i32_on_stack), f64_convert_i32_s, Numeric),
278
    (Some(i32_on_stack), f64_convert_i32_u, Numeric),
279
    (Some(i64_on_stack), f64_convert_i64_s, Numeric),
280
    (Some(i64_on_stack), f64_convert_i64_u, Numeric),
281
    (Some(f32_on_stack), f64_promote_f32, Numeric),
282
    (Some(f32_on_stack), i32_reinterpret_f32, Numeric),
283
    (Some(f64_on_stack), i64_reinterpret_f64, Numeric),
284
    (Some(i32_on_stack), f32_reinterpret_i32, Numeric),
285
    (Some(i64_on_stack), f64_reinterpret_i64, Numeric),
286
    (Some(extendable_i32_on_stack), i32_extend_8_s, Numeric),
287
    (Some(extendable_i32_on_stack), i32_extend_16_s, Numeric),
288
    (Some(extendable_i64_on_stack), i64_extend_8_s, Numeric),
289
    (Some(extendable_i64_on_stack), i64_extend_16_s, Numeric),
290
    (Some(extendable_i64_on_stack), i64_extend_32_s, Numeric),
291
    (Some(nontrapping_f32_on_stack), i32_trunc_sat_f32_s, Numeric),
292
    (Some(nontrapping_f32_on_stack), i32_trunc_sat_f32_u, Numeric),
293
    (Some(nontrapping_f64_on_stack), i32_trunc_sat_f64_s, Numeric),
294
    (Some(nontrapping_f64_on_stack), i32_trunc_sat_f64_u, Numeric),
295
    (Some(nontrapping_f32_on_stack), i64_trunc_sat_f32_s, Numeric),
296
    (Some(nontrapping_f32_on_stack), i64_trunc_sat_f32_u, Numeric),
297
    (Some(nontrapping_f64_on_stack), i64_trunc_sat_f64_s, Numeric),
298
    (Some(nontrapping_f64_on_stack), i64_trunc_sat_f64_u, Numeric),
299
    // Reference instructions.
300
    (Some(ref_null_valid), ref_null, Reference),
301
    (Some(ref_func_valid), ref_func, Reference),
302
    (Some(ref_as_non_null_valid), ref_as_non_null, Reference),
303
    (Some(ref_eq_valid), ref_eq, Reference),
304
    (Some(ref_test_valid), ref_test, Reference),
305
    (Some(ref_cast_valid), ref_cast, Reference),
306
    (Some(ref_is_null_valid), ref_is_null, Reference),
307
    (Some(table_fill_valid), table_fill, Reference),
308
    (Some(table_set_valid), table_set, Reference),
309
    (Some(table_get_valid), table_get, Reference),
310
    (Some(table_size_valid), table_size, Reference),
311
    (Some(table_grow_valid), table_grow, Reference),
312
    (Some(table_copy_valid), table_copy, Reference),
313
    (Some(table_init_valid), table_init, Reference),
314
    (Some(elem_drop_valid), elem_drop, Reference),
315
    // Aggregate instructions.
316
    (Some(struct_new_valid), struct_new, Aggregate),
317
    (Some(struct_new_default_valid), struct_new_default, Aggregate),
318
    (Some(struct_get_valid), struct_get, Aggregate),
319
    (Some(struct_set_valid), struct_set, Aggregate),
320
    (Some(array_new_valid), array_new, Aggregate),
321
    (Some(array_new_fixed_valid), array_new_fixed, Aggregate),
322
    (Some(array_new_default_valid), array_new_default, Aggregate),
323
    (Some(array_new_data_valid), array_new_data, Aggregate),
324
    (Some(array_new_elem_valid), array_new_elem, Aggregate),
325
    (Some(array_get_valid), array_get, Aggregate),
326
    (Some(array_set_valid), array_set, Aggregate),
327
    (Some(array_len_valid), array_len, Aggregate),
328
    (Some(array_fill_valid), array_fill, Aggregate),
329
    (Some(array_copy_valid), array_copy, Aggregate),
330
    (Some(array_init_data_valid), array_init_data, Aggregate),
331
    (Some(array_init_elem_valid), array_init_elem, Aggregate),
332
    (Some(ref_i31_valid), ref_i31, Aggregate),
333
    (Some(i31_get_valid), i31_get, Aggregate),
334
    (Some(any_convert_extern_valid), any_convert_extern, Aggregate),
335
    (Some(extern_convert_any_valid), extern_convert_any, Aggregate),
336
    // SIMD instructions.
337
    (Some(simd_have_memory_and_offset), v128_load, Vector),
338
    (Some(simd_have_memory_and_offset), v128_load8x8s, Vector),
339
    (Some(simd_have_memory_and_offset), v128_load8x8u, Vector),
340
    (Some(simd_have_memory_and_offset), v128_load16x4s, Vector),
341
    (Some(simd_have_memory_and_offset), v128_load16x4u, Vector),
342
    (Some(simd_have_memory_and_offset), v128_load32x2s, Vector),
343
    (Some(simd_have_memory_and_offset), v128_load32x2u, Vector),
344
    (Some(simd_have_memory_and_offset), v128_load8_splat, Vector),
345
    (Some(simd_have_memory_and_offset), v128_load16_splat, Vector),
346
    (Some(simd_have_memory_and_offset), v128_load32_splat, Vector),
347
    (Some(simd_have_memory_and_offset), v128_load64_splat, Vector),
348
    (Some(simd_have_memory_and_offset), v128_load32_zero, Vector),
349
    (Some(simd_have_memory_and_offset), v128_load64_zero, Vector),
350
    (Some(simd_v128_store_valid), v128_store, Vector),
351
    (Some(simd_load_lane_valid), v128_load8_lane, Vector),
352
    (Some(simd_load_lane_valid), v128_load16_lane, Vector),
353
    (Some(simd_load_lane_valid), v128_load32_lane, Vector),
354
    (Some(simd_load_lane_valid), v128_load64_lane, Vector),
355
    (Some(simd_store_lane_valid), v128_store8_lane, Vector),
356
    (Some(simd_store_lane_valid), v128_store16_lane, Vector),
357
    (Some(simd_store_lane_valid), v128_store32_lane, Vector),
358
    (Some(simd_store_lane_valid), v128_store64_lane, Vector),
359
    (Some(simd_enabled), v128_const, Vector),
360
    (Some(simd_v128_v128_on_stack), i8x16_shuffle, Vector),
361
    (Some(simd_v128_on_stack), i8x16_extract_lane_s, Vector),
362
    (Some(simd_v128_on_stack), i8x16_extract_lane_u, Vector),
363
    (Some(simd_v128_i32_on_stack), i8x16_replace_lane, Vector),
364
    (Some(simd_v128_on_stack), i16x8_extract_lane_s, Vector),
365
    (Some(simd_v128_on_stack), i16x8_extract_lane_u, Vector),
366
    (Some(simd_v128_i32_on_stack), i16x8_replace_lane, Vector),
367
    (Some(simd_v128_on_stack), i32x4_extract_lane, Vector),
368
    (Some(simd_v128_i32_on_stack), i32x4_replace_lane, Vector),
369
    (Some(simd_v128_on_stack), i64x2_extract_lane, Vector),
370
    (Some(simd_v128_i64_on_stack), i64x2_replace_lane, Vector),
371
    (Some(simd_v128_on_stack), f32x4_extract_lane, Vector),
372
    (Some(simd_v128_f32_on_stack), f32x4_replace_lane, Vector),
373
    (Some(simd_v128_on_stack), f64x2_extract_lane, Vector),
374
    (Some(simd_v128_f64_on_stack), f64x2_replace_lane, Vector),
375
    (Some(simd_i32_on_stack), i8x16_splat, Vector),
376
    (Some(simd_i32_on_stack), i16x8_splat, Vector),
377
    (Some(simd_i32_on_stack), i32x4_splat, Vector),
378
    (Some(simd_i64_on_stack), i64x2_splat, Vector),
379
    (Some(simd_f32_on_stack), f32x4_splat, Vector),
380
    (Some(simd_f64_on_stack), f64x2_splat, Vector),
381
    (Some(simd_v128_v128_on_stack), i8x16_swizzle, Vector),
382
    (Some(simd_v128_v128_on_stack_relaxed), i8x16_relaxed_swizzle, Vector),
383
    (Some(simd_v128_v128_v128_on_stack), v128_bitselect, Vector),
384
    (Some(simd_v128_v128_v128_on_stack_relaxed), i8x16_relaxed_laneselect, Vector),
385
    (Some(simd_v128_v128_v128_on_stack_relaxed), i16x8_relaxed_laneselect, Vector),
386
    (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_relaxed_laneselect, Vector),
387
    (Some(simd_v128_v128_v128_on_stack_relaxed), i64x2_relaxed_laneselect, Vector),
388
    (Some(simd_v128_v128_on_stack), i8x16_eq, Vector),
389
    (Some(simd_v128_v128_on_stack), i8x16_ne, Vector),
390
    (Some(simd_v128_v128_on_stack), i8x16_lt_s, Vector),
391
    (Some(simd_v128_v128_on_stack), i8x16_lt_u, Vector),
392
    (Some(simd_v128_v128_on_stack), i8x16_gt_s, Vector),
393
    (Some(simd_v128_v128_on_stack), i8x16_gt_u, Vector),
394
    (Some(simd_v128_v128_on_stack), i8x16_le_s, Vector),
395
    (Some(simd_v128_v128_on_stack), i8x16_le_u, Vector),
396
    (Some(simd_v128_v128_on_stack), i8x16_ge_s, Vector),
397
    (Some(simd_v128_v128_on_stack), i8x16_ge_u, Vector),
398
    (Some(simd_v128_v128_on_stack), i16x8_eq, Vector),
399
    (Some(simd_v128_v128_on_stack), i16x8_ne, Vector),
400
    (Some(simd_v128_v128_on_stack), i16x8_lt_s, Vector),
401
    (Some(simd_v128_v128_on_stack), i16x8_lt_u, Vector),
402
    (Some(simd_v128_v128_on_stack), i16x8_gt_s, Vector),
403
    (Some(simd_v128_v128_on_stack), i16x8_gt_u, Vector),
404
    (Some(simd_v128_v128_on_stack), i16x8_le_s, Vector),
405
    (Some(simd_v128_v128_on_stack), i16x8_le_u, Vector),
406
    (Some(simd_v128_v128_on_stack), i16x8_ge_s, Vector),
407
    (Some(simd_v128_v128_on_stack), i16x8_ge_u, Vector),
408
    (Some(simd_v128_v128_on_stack), i32x4_eq, Vector),
409
    (Some(simd_v128_v128_on_stack), i32x4_ne, Vector),
410
    (Some(simd_v128_v128_on_stack), i32x4_lt_s, Vector),
411
    (Some(simd_v128_v128_on_stack), i32x4_lt_u, Vector),
412
    (Some(simd_v128_v128_on_stack), i32x4_gt_s, Vector),
413
    (Some(simd_v128_v128_on_stack), i32x4_gt_u, Vector),
414
    (Some(simd_v128_v128_on_stack), i32x4_le_s, Vector),
415
    (Some(simd_v128_v128_on_stack), i32x4_le_u, Vector),
416
    (Some(simd_v128_v128_on_stack), i32x4_ge_s, Vector),
417
    (Some(simd_v128_v128_on_stack), i32x4_ge_u, Vector),
418
    (Some(simd_v128_v128_on_stack), i64x2_eq, Vector),
419
    (Some(simd_v128_v128_on_stack), i64x2_ne, Vector),
420
    (Some(simd_v128_v128_on_stack), i64x2_lt_s, Vector),
421
    (Some(simd_v128_v128_on_stack), i64x2_gt_s, Vector),
422
    (Some(simd_v128_v128_on_stack), i64x2_le_s, Vector),
423
    (Some(simd_v128_v128_on_stack), i64x2_ge_s, Vector),
424
    (Some(simd_v128_v128_on_stack), f32x4_eq, Vector),
425
    (Some(simd_v128_v128_on_stack), f32x4_ne, Vector),
426
    (Some(simd_v128_v128_on_stack), f32x4_lt, Vector),
427
    (Some(simd_v128_v128_on_stack), f32x4_gt, Vector),
428
    (Some(simd_v128_v128_on_stack), f32x4_le, Vector),
429
    (Some(simd_v128_v128_on_stack), f32x4_ge, Vector),
430
    (Some(simd_v128_v128_on_stack), f64x2_eq, Vector),
431
    (Some(simd_v128_v128_on_stack), f64x2_ne, Vector),
432
    (Some(simd_v128_v128_on_stack), f64x2_lt, Vector),
433
    (Some(simd_v128_v128_on_stack), f64x2_gt, Vector),
434
    (Some(simd_v128_v128_on_stack), f64x2_le, Vector),
435
    (Some(simd_v128_v128_on_stack), f64x2_ge, Vector),
436
    (Some(simd_v128_on_stack), v128_not, Vector),
437
    (Some(simd_v128_v128_on_stack), v128_and, Vector),
438
    (Some(simd_v128_v128_on_stack), v128_and_not, Vector),
439
    (Some(simd_v128_v128_on_stack), v128_or, Vector),
440
    (Some(simd_v128_v128_on_stack), v128_xor, Vector),
441
    (Some(simd_v128_v128_on_stack), v128_any_true, Vector),
442
    (Some(simd_v128_on_stack), i8x16_abs, Vector),
443
    (Some(simd_v128_on_stack), i8x16_neg, Vector),
444
    (Some(simd_v128_on_stack), i8x16_popcnt, Vector),
445
    (Some(simd_v128_on_stack), i8x16_all_true, Vector),
446
    (Some(simd_v128_on_stack), i8x16_bitmask, Vector),
447
    (Some(simd_v128_v128_on_stack), i8x16_narrow_i16x8s, Vector),
448
    (Some(simd_v128_v128_on_stack), i8x16_narrow_i16x8u, Vector),
449
    (Some(simd_v128_i32_on_stack), i8x16_shl, Vector),
450
    (Some(simd_v128_i32_on_stack), i8x16_shr_s, Vector),
451
    (Some(simd_v128_i32_on_stack), i8x16_shr_u, Vector),
452
    (Some(simd_v128_v128_on_stack), i8x16_add, Vector),
453
    (Some(simd_v128_v128_on_stack), i8x16_add_sat_s, Vector),
454
    (Some(simd_v128_v128_on_stack), i8x16_add_sat_u, Vector),
455
    (Some(simd_v128_v128_on_stack), i8x16_sub, Vector),
456
    (Some(simd_v128_v128_on_stack), i8x16_sub_sat_s, Vector),
457
    (Some(simd_v128_v128_on_stack), i8x16_sub_sat_u, Vector),
458
    (Some(simd_v128_v128_on_stack), i8x16_min_s, Vector),
459
    (Some(simd_v128_v128_on_stack), i8x16_min_u, Vector),
460
    (Some(simd_v128_v128_on_stack), i8x16_max_s, Vector),
461
    (Some(simd_v128_v128_on_stack), i8x16_max_u, Vector),
462
    (Some(simd_v128_v128_on_stack), i8x16_avgr_u, Vector),
463
    (Some(simd_v128_on_stack), i16x8_extadd_pairwise_i8x16s, Vector),
464
    (Some(simd_v128_on_stack), i16x8_extadd_pairwise_i8x16u, Vector),
465
    (Some(simd_v128_on_stack), i16x8_abs, Vector),
466
    (Some(simd_v128_on_stack), i16x8_neg, Vector),
467
    (Some(simd_v128_v128_on_stack), i16x8q15_mulr_sat_s, Vector),
468
    (Some(simd_v128_on_stack), i16x8_all_true, Vector),
469
    (Some(simd_v128_on_stack), i16x8_bitmask, Vector),
470
    (Some(simd_v128_v128_on_stack), i16x8_narrow_i32x4s, Vector),
471
    (Some(simd_v128_v128_on_stack), i16x8_narrow_i32x4u, Vector),
472
    (Some(simd_v128_on_stack), i16x8_extend_low_i8x16s, Vector),
473
    (Some(simd_v128_on_stack), i16x8_extend_high_i8x16s, Vector),
474
    (Some(simd_v128_on_stack), i16x8_extend_low_i8x16u, Vector),
475
    (Some(simd_v128_on_stack), i16x8_extend_high_i8x16u, Vector),
476
    (Some(simd_v128_i32_on_stack), i16x8_shl, Vector),
477
    (Some(simd_v128_i32_on_stack), i16x8_shr_s, Vector),
478
    (Some(simd_v128_i32_on_stack), i16x8_shr_u, Vector),
479
    (Some(simd_v128_v128_on_stack), i16x8_add, Vector),
480
    (Some(simd_v128_v128_on_stack), i16x8_add_sat_s, Vector),
481
    (Some(simd_v128_v128_on_stack), i16x8_add_sat_u, Vector),
482
    (Some(simd_v128_v128_on_stack), i16x8_sub, Vector),
483
    (Some(simd_v128_v128_on_stack), i16x8_sub_sat_s, Vector),
484
    (Some(simd_v128_v128_on_stack), i16x8_sub_sat_u, Vector),
485
    (Some(simd_v128_v128_on_stack), i16x8_mul, Vector),
486
    (Some(simd_v128_v128_on_stack), i16x8_min_s, Vector),
487
    (Some(simd_v128_v128_on_stack), i16x8_min_u, Vector),
488
    (Some(simd_v128_v128_on_stack), i16x8_max_s, Vector),
489
    (Some(simd_v128_v128_on_stack), i16x8_max_u, Vector),
490
    (Some(simd_v128_v128_on_stack), i16x8_avgr_u, Vector),
491
    (Some(simd_v128_v128_on_stack), i16x8_extmul_low_i8x16s, Vector),
492
    (Some(simd_v128_v128_on_stack), i16x8_extmul_high_i8x16s, Vector),
493
    (Some(simd_v128_v128_on_stack), i16x8_extmul_low_i8x16u, Vector),
494
    (Some(simd_v128_v128_on_stack), i16x8_extmul_high_i8x16u, Vector),
495
    (Some(simd_v128_on_stack), i32x4_extadd_pairwise_i16x8s, Vector),
496
    (Some(simd_v128_on_stack), i32x4_extadd_pairwise_i16x8u, Vector),
497
    (Some(simd_v128_on_stack), i32x4_abs, Vector),
498
    (Some(simd_v128_on_stack), i32x4_neg, Vector),
499
    (Some(simd_v128_on_stack), i32x4_all_true, Vector),
500
    (Some(simd_v128_on_stack), i32x4_bitmask, Vector),
501
    (Some(simd_v128_on_stack), i32x4_extend_low_i16x8s, Vector),
502
    (Some(simd_v128_on_stack), i32x4_extend_high_i16x8s, Vector),
503
    (Some(simd_v128_on_stack), i32x4_extend_low_i16x8u, Vector),
504
    (Some(simd_v128_on_stack), i32x4_extend_high_i16x8u, Vector),
505
    (Some(simd_v128_i32_on_stack), i32x4_shl, Vector),
506
    (Some(simd_v128_i32_on_stack), i32x4_shr_s, Vector),
507
    (Some(simd_v128_i32_on_stack), i32x4_shr_u, Vector),
508
    (Some(simd_v128_v128_on_stack), i32x4_add, Vector),
509
    (Some(simd_v128_v128_on_stack), i32x4_sub, Vector),
510
    (Some(simd_v128_v128_on_stack), i32x4_mul, Vector),
511
    (Some(simd_v128_v128_on_stack), i32x4_min_s, Vector),
512
    (Some(simd_v128_v128_on_stack), i32x4_min_u, Vector),
513
    (Some(simd_v128_v128_on_stack), i32x4_max_s, Vector),
514
    (Some(simd_v128_v128_on_stack), i32x4_max_u, Vector),
515
    (Some(simd_v128_v128_on_stack), i32x4_dot_i16x8s, Vector),
516
    (Some(simd_v128_v128_on_stack), i32x4_extmul_low_i16x8s, Vector),
517
    (Some(simd_v128_v128_on_stack), i32x4_extmul_high_i16x8s, Vector),
518
    (Some(simd_v128_v128_on_stack), i32x4_extmul_low_i16x8u, Vector),
519
    (Some(simd_v128_v128_on_stack), i32x4_extmul_high_i16x8u, Vector),
520
    (Some(simd_v128_on_stack), i64x2_abs, Vector),
521
    (Some(simd_v128_on_stack), i64x2_neg, Vector),
522
    (Some(simd_v128_on_stack), i64x2_all_true, Vector),
523
    (Some(simd_v128_on_stack), i64x2_bitmask, Vector),
524
    (Some(simd_v128_on_stack), i64x2_extend_low_i32x4s, Vector),
525
    (Some(simd_v128_on_stack), i64x2_extend_high_i32x4s, Vector),
526
    (Some(simd_v128_on_stack), i64x2_extend_low_i32x4u, Vector),
527
    (Some(simd_v128_on_stack), i64x2_extend_high_i32x4u, Vector),
528
    (Some(simd_v128_i32_on_stack), i64x2_shl, Vector),
529
    (Some(simd_v128_i32_on_stack), i64x2_shr_s, Vector),
530
    (Some(simd_v128_i32_on_stack), i64x2_shr_u, Vector),
531
    (Some(simd_v128_v128_on_stack), i64x2_add, Vector),
532
    (Some(simd_v128_v128_on_stack), i64x2_sub, Vector),
533
    (Some(simd_v128_v128_on_stack), i64x2_mul, Vector),
534
    (Some(simd_v128_v128_on_stack), i64x2_extmul_low_i32x4s, Vector),
535
    (Some(simd_v128_v128_on_stack), i64x2_extmul_high_i32x4s, Vector),
536
    (Some(simd_v128_v128_on_stack), i64x2_extmul_low_i32x4u, Vector),
537
    (Some(simd_v128_v128_on_stack), i64x2_extmul_high_i32x4u, Vector),
538
    (Some(simd_v128_on_stack), f32x4_ceil, Vector),
539
    (Some(simd_v128_on_stack), f32x4_floor, Vector),
540
    (Some(simd_v128_on_stack), f32x4_trunc, Vector),
541
    (Some(simd_v128_on_stack), f32x4_nearest, Vector),
542
    (Some(simd_v128_on_stack), f32x4_abs, Vector),
543
    (Some(simd_v128_on_stack), f32x4_neg, Vector),
544
    (Some(simd_v128_on_stack), f32x4_sqrt, Vector),
545
    (Some(simd_v128_v128_on_stack), f32x4_add, Vector),
546
    (Some(simd_v128_v128_on_stack), f32x4_sub, Vector),
547
    (Some(simd_v128_v128_on_stack), f32x4_mul, Vector),
548
    (Some(simd_v128_v128_on_stack), f32x4_div, Vector),
549
    (Some(simd_v128_v128_on_stack), f32x4_min, Vector),
550
    (Some(simd_v128_v128_on_stack), f32x4_max, Vector),
551
    (Some(simd_v128_v128_on_stack), f32x4p_min, Vector),
552
    (Some(simd_v128_v128_on_stack), f32x4p_max, Vector),
553
    (Some(simd_v128_on_stack), f64x2_ceil, Vector),
554
    (Some(simd_v128_on_stack), f64x2_floor, Vector),
555
    (Some(simd_v128_on_stack), f64x2_trunc, Vector),
556
    (Some(simd_v128_on_stack), f64x2_nearest, Vector),
557
    (Some(simd_v128_on_stack), f64x2_abs, Vector),
558
    (Some(simd_v128_on_stack), f64x2_neg, Vector),
559
    (Some(simd_v128_on_stack), f64x2_sqrt, Vector),
560
    (Some(simd_v128_v128_on_stack), f64x2_add, Vector),
561
    (Some(simd_v128_v128_on_stack), f64x2_sub, Vector),
562
    (Some(simd_v128_v128_on_stack), f64x2_mul, Vector),
563
    (Some(simd_v128_v128_on_stack), f64x2_div, Vector),
564
    (Some(simd_v128_v128_on_stack), f64x2_min, Vector),
565
    (Some(simd_v128_v128_on_stack), f64x2_max, Vector),
566
    (Some(simd_v128_v128_on_stack), f64x2p_min, Vector),
567
    (Some(simd_v128_v128_on_stack), f64x2p_max, Vector),
568
    (Some(simd_v128_on_stack), i32x4_trunc_sat_f32x4s, Vector),
569
    (Some(simd_v128_on_stack), i32x4_trunc_sat_f32x4u, Vector),
570
    (Some(simd_v128_on_stack), f32x4_convert_i32x4s, Vector),
571
    (Some(simd_v128_on_stack), f32x4_convert_i32x4u, Vector),
572
    (Some(simd_v128_on_stack), i32x4_trunc_sat_f64x2s_zero, Vector),
573
    (Some(simd_v128_on_stack), i32x4_trunc_sat_f64x2u_zero, Vector),
574
    (Some(simd_v128_on_stack), f64x2_convert_low_i32x4s, Vector),
575
    (Some(simd_v128_on_stack), f64x2_convert_low_i32x4u, Vector),
576
    (Some(simd_v128_on_stack), f32x4_demote_f64x2_zero, Vector),
577
    (Some(simd_v128_on_stack), f64x2_promote_low_f32x4, Vector),
578
    (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_f32x4s, Vector),
579
    (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_f32x4u, Vector),
580
    (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_f64x2s_zero, Vector),
581
    (Some(simd_v128_on_stack_relaxed), i32x4_relaxed_trunc_f64x2u_zero, Vector),
582
    (Some(simd_v128_v128_v128_on_stack_relaxed), f32x4_relaxed_madd, Vector),
583
    (Some(simd_v128_v128_v128_on_stack_relaxed), f32x4_relaxed_nmadd, Vector),
584
    (Some(simd_v128_v128_v128_on_stack_relaxed), f64x2_relaxed_madd, Vector),
585
    (Some(simd_v128_v128_v128_on_stack_relaxed), f64x2_relaxed_nmadd, Vector),
586
    (Some(simd_v128_v128_on_stack_relaxed), f32x4_relaxed_min, Vector),
587
    (Some(simd_v128_v128_on_stack_relaxed), f32x4_relaxed_max, Vector),
588
    (Some(simd_v128_v128_on_stack_relaxed), f64x2_relaxed_min, Vector),
589
    (Some(simd_v128_v128_on_stack_relaxed), f64x2_relaxed_max, Vector),
590
    (Some(simd_v128_v128_on_stack_relaxed), i16x8_relaxed_q15mulr_s, Vector),
591
    (Some(simd_v128_v128_on_stack_relaxed), i16x8_relaxed_dot_i8x16_i7x16_s, Vector),
592
    (Some(simd_v128_v128_v128_on_stack_relaxed), i32x4_relaxed_dot_i8x16_i7x16_add_s, Vector),
593
}
594
595
pub(crate) struct CodeBuilderAllocations {
596
    // The control labels in scope right now.
597
    controls: Vec<Control>,
598
599
    // The types on the operand stack right now.
600
    operands: Vec<Option<ValType>>,
601
602
    // Dynamic set of options of instruction we can generate that are known to
603
    // be valid right now.
604
    options: Vec<(
605
        fn(&mut Unstructured, &Module, &mut CodeBuilder, &mut Vec<Instruction>) -> Result<()>,
606
        u32,
607
    )>,
608
609
    // Cached information about the module that we're generating functions for,
610
    // used to speed up validity checks. The mutable globals map is a map of the
611
    // type of global to the global indices which have that type (and they're
612
    // all mutable).
613
    mutable_globals: BTreeMap<ValType, Vec<u32>>,
614
615
    // Like mutable globals above this is a map from function types to the list
616
    // of functions that have that function type.
617
    functions: BTreeMap<Rc<FuncType>, Vec<u32>>,
618
619
    // Like functions above this is a map from tag types to the list of tags
620
    // have that tag type.
621
    tags: BTreeMap<Vec<ValType>, Vec<u32>>,
622
623
    // Tables in this module which have a funcref element type.
624
    table32_with_funcref: Vec<u32>,
625
    table64_with_funcref: Vec<u32>,
626
627
    // Functions that are referenced in the module through globals and segments.
628
    referenced_functions: Vec<u32>,
629
630
    // Precomputed tables/element segments that can be used for `table.init`,
631
    // stored as (segment, table).
632
    table32_init: Vec<(u32, u32)>,
633
    table64_init: Vec<(u32, u32)>,
634
635
    // Precomputed valid tables to copy between, stored in (src, dst) order.
636
    table_copy_32_to_32: Vec<(u32, u32)>,
637
    table_copy_32_to_64: Vec<(u32, u32)>,
638
    table_copy_64_to_32: Vec<(u32, u32)>,
639
    table_copy_64_to_64: Vec<(u32, u32)>,
640
641
    // Lists of table/memory indices which are either 32-bit or 64-bit. This is
642
    // used for faster lookup in validating instructions to know which memories
643
    // have which types. For example if there are no 64-bit memories then we
644
    // shouldn't ever look for i64 on the stack for `i32.load`.
645
    memory32: Vec<u32>,
646
    memory64: Vec<u32>,
647
    table32: Vec<u32>,
648
    table64: Vec<u32>,
649
650
    // State used when dropping operands to avoid dropping them into the ether
651
    // but instead folding their final values into module state, at this time
652
    // chosen to be exported globals.
653
    globals_cnt: u32,
654
    new_globals: Vec<(ValType, ConstExpr)>,
655
    global_dropped_i32: Option<u32>,
656
    global_dropped_i64: Option<u32>,
657
    global_dropped_f32: Option<u32>,
658
    global_dropped_f64: Option<u32>,
659
    global_dropped_v128: Option<u32>,
660
661
    // Indicates that additional exports cannot be generated. This will be true
662
    // if the `Config` specifies exactly which exports should be present.
663
    disallow_exporting: bool,
664
}
665
666
pub(crate) struct CodeBuilder<'a> {
667
    func_ty: &'a FuncType,
668
    locals: &'a mut Vec<ValType>,
669
    allocs: &'a mut CodeBuilderAllocations,
670
671
    // Temporary locals injected and used by nan canonicalization. Note that
672
    // this list of extra locals is appended to `self.locals` at the end of code
673
    // generation, and it's kept separate here to avoid using these locals in
674
    // `local.get` and similar instructions.
675
    extra_locals: Vec<ValType>,
676
    f32_scratch: Option<usize>,
677
    f64_scratch: Option<usize>,
678
    v128_scratch: Option<usize>,
679
}
680
681
/// A control frame.
682
#[derive(Debug, Clone)]
683
struct Control {
684
    kind: ControlKind,
685
    /// Value types that must be on the stack when entering this control frame.
686
    params: Vec<ValType>,
687
    /// Value types that are left on the stack when exiting this control frame.
688
    results: Vec<ValType>,
689
    /// How far down the operand stack instructions inside this control frame
690
    /// can reach.
691
    height: usize,
692
}
693
694
impl Control {
695
277k
    fn label_types(&self) -> &[ValType] {
696
277k
        if self.kind == ControlKind::Loop {
697
15.3k
            &self.params
698
        } else {
699
261k
            &self.results
700
        }
701
277k
    }
702
}
703
704
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
705
enum ControlKind {
706
    Block,
707
    If,
708
    Loop,
709
    TryTable,
710
}
711
712
enum Float {
713
    F32,
714
    F64,
715
    F32x4,
716
    F64x2,
717
}
718
719
impl CodeBuilderAllocations {
720
5.67k
    pub(crate) fn new(module: &Module, disallow_exporting: bool) -> Self {
721
5.67k
        let mut mutable_globals = BTreeMap::new();
722
5.67k
        for (i, global) in module.globals.iter().enumerate() {
723
4.63k
            if global.mutable {
724
3.23k
                mutable_globals
725
3.23k
                    .entry(global.val_type)
726
3.23k
                    .or_insert(Vec::new())
727
3.23k
                    .push(i as u32);
728
3.23k
            }
729
        }
730
731
5.67k
        let mut tags = BTreeMap::new();
732
5.67k
        for (idx, tag_type) in module.tags() {
733
0
            tags.entry(tag_type.func_type.params.to_vec())
734
0
                .or_insert(Vec::new())
735
0
                .push(idx);
736
0
        }
737
738
5.67k
        let mut functions = BTreeMap::new();
739
17.3k
        for (idx, func) in module.funcs() {
740
17.3k
            functions
741
17.3k
                .entry(func.clone())
742
17.3k
                .or_insert(Vec::new())
743
17.3k
                .push(idx);
744
17.3k
        }
745
746
5.67k
        let mut table32_with_funcref = Vec::new();
747
5.67k
        let mut table64_with_funcref = Vec::new();
748
5.67k
        let mut table32_tys = Vec::new();
749
5.67k
        let mut table64_tys = Vec::new();
750
5.67k
        for (i, table) in module.tables.iter().enumerate() {
751
1.32k
            let funcref_dst = if table.table64 {
752
0
                table64_tys.push(table.element_type);
753
0
                &mut table64_with_funcref
754
            } else {
755
1.32k
                table32_tys.push(table.element_type);
756
1.32k
                &mut table32_with_funcref
757
            };
758
1.32k
            if table.element_type == RefType::FUNCREF {
759
1.32k
                funcref_dst.push(i as u32);
760
1.32k
            }
761
        }
762
763
5.67k
        let mut referenced_functions = BTreeSet::new();
764
5.67k
        for (_, expr) in module.defined_globals.iter() {
765
2.50k
            if let Some(i) = expr.get_ref_func() {
766
0
                referenced_functions.insert(i);
767
2.50k
            }
768
        }
769
770
5.67k
        let mut table32_init = Vec::new();
771
5.67k
        let mut table64_init = Vec::new();
772
5.67k
        for (i, g) in module.elems.iter().enumerate() {
773
1.58k
            match &g.items {
774
0
                Elements::Expressions(e) => {
775
0
                    let iter = e.iter().filter_map(|e| e.get_ref_func());
776
0
                    referenced_functions.extend(iter);
777
0
                }
778
1.58k
                Elements::Functions(e) => {
779
1.58k
                    referenced_functions.extend(e.iter().cloned());
780
1.58k
                }
781
            }
782
1.58k
            for (j, table) in module.tables.iter().enumerate() {
783
1.58k
                if module.ref_type_is_sub_type(g.ty, table.element_type) {
784
1.58k
                    let dst = if table.table64 {
785
0
                        &mut table64_init
786
                    } else {
787
1.58k
                        &mut table32_init
788
                    };
789
1.58k
                    dst.push((i as u32, j as u32));
790
0
                }
791
            }
792
        }
793
794
5.67k
        let mut memory32 = Vec::new();
795
5.67k
        let mut memory64 = Vec::new();
796
5.67k
        for (i, mem) in module.memories.iter().enumerate() {
797
1.74k
            if mem.memory64 {
798
0
                memory64.push(i as u32);
799
1.74k
            } else {
800
1.74k
                memory32.push(i as u32);
801
1.74k
            }
802
        }
803
804
5.67k
        let mut table32 = Vec::new();
805
5.67k
        let mut table64 = Vec::new();
806
5.67k
        let mut table_copy_32_to_32 = Vec::new();
807
5.67k
        let mut table_copy_32_to_64 = Vec::new();
808
5.67k
        let mut table_copy_64_to_32 = Vec::new();
809
5.67k
        let mut table_copy_64_to_64 = Vec::new();
810
5.67k
        for (i, t) in module.tables.iter().enumerate() {
811
1.32k
            if t.table64 {
812
0
                table64.push(i as u32);
813
1.32k
            } else {
814
1.32k
                table32.push(i as u32);
815
1.32k
            }
816
817
1.32k
            for (j, t2) in module.tables.iter().enumerate() {
818
1.32k
                if module.val_type_is_sub_type(t.element_type.into(), t2.element_type.into()) {
819
1.32k
                    let dst = match (t.table64, t2.table64) {
820
1.32k
                        (false, false) => &mut table_copy_32_to_32,
821
0
                        (false, true) => &mut table_copy_32_to_64,
822
0
                        (true, false) => &mut table_copy_64_to_32,
823
0
                        (true, true) => &mut table_copy_64_to_64,
824
                    };
825
1.32k
                    dst.push((i as u32, j as u32));
826
0
                }
827
            }
828
        }
829
830
5.67k
        let mut global_dropped_i32 = None;
831
5.67k
        let mut global_dropped_i64 = None;
832
5.67k
        let mut global_dropped_f32 = None;
833
5.67k
        let mut global_dropped_f64 = None;
834
5.67k
        let mut global_dropped_v128 = None;
835
5.67k
836
5.67k
        // If we can't export additional globals, try to use existing exported
837
5.67k
        // mutable globals for dropped values.
838
5.67k
        if disallow_exporting {
839
0
            for (_, kind, index) in module.exports.iter() {
840
0
                if *kind == ExportKind::Global {
841
0
                    let ty = module.globals[*index as usize];
842
0
                    if ty.mutable {
843
0
                        match ty.val_type {
844
                            ValType::I32 => {
845
0
                                if global_dropped_i32.is_none() {
846
0
                                    global_dropped_i32 = Some(*index)
847
                                } else {
848
0
                                    global_dropped_f32 = Some(*index)
849
                                }
850
                            }
851
                            ValType::I64 => {
852
0
                                if global_dropped_i64.is_none() {
853
0
                                    global_dropped_i64 = Some(*index)
854
                                } else {
855
0
                                    global_dropped_f64 = Some(*index)
856
                                }
857
                            }
858
0
                            ValType::V128 => global_dropped_v128 = Some(*index),
859
0
                            _ => {}
860
                        }
861
0
                    }
862
0
                }
863
            }
864
5.67k
        }
865
866
5.67k
        CodeBuilderAllocations {
867
5.67k
            controls: Vec::with_capacity(4),
868
5.67k
            operands: Vec::with_capacity(16),
869
5.67k
            options: Vec::with_capacity(NUM_OPTIONS),
870
5.67k
            functions,
871
5.67k
            tags,
872
5.67k
            mutable_globals,
873
5.67k
            table32_with_funcref,
874
5.67k
            table64_with_funcref,
875
5.67k
            referenced_functions: referenced_functions.into_iter().collect(),
876
5.67k
            table32_init,
877
5.67k
            table64_init,
878
5.67k
            table_copy_32_to_32,
879
5.67k
            table_copy_32_to_64,
880
5.67k
            table_copy_64_to_32,
881
5.67k
            table_copy_64_to_64,
882
5.67k
            memory32,
883
5.67k
            memory64,
884
5.67k
            table32,
885
5.67k
            table64,
886
5.67k
887
5.67k
            global_dropped_i32,
888
5.67k
            global_dropped_i64,
889
5.67k
            global_dropped_f32,
890
5.67k
            global_dropped_f64,
891
5.67k
            global_dropped_v128,
892
5.67k
            globals_cnt: module.globals.len() as u32,
893
5.67k
            new_globals: Vec::new(),
894
5.67k
            disallow_exporting,
895
5.67k
        }
896
5.67k
    }
897
898
15.8k
    pub(crate) fn builder<'a>(
899
15.8k
        &'a mut self,
900
15.8k
        func_ty: &'a FuncType,
901
15.8k
        locals: &'a mut Vec<ValType>,
902
15.8k
    ) -> CodeBuilder<'a> {
903
15.8k
        self.controls.clear();
904
15.8k
        self.controls.push(Control {
905
15.8k
            kind: ControlKind::Block,
906
15.8k
            params: vec![],
907
15.8k
            results: func_ty.results.to_vec(),
908
15.8k
            height: 0,
909
15.8k
        });
910
15.8k
911
15.8k
        self.operands.clear();
912
15.8k
        self.options.clear();
913
15.8k
914
15.8k
        CodeBuilder {
915
15.8k
            func_ty,
916
15.8k
            locals,
917
15.8k
            allocs: self,
918
15.8k
            extra_locals: Vec::new(),
919
15.8k
            f32_scratch: None,
920
15.8k
            f64_scratch: None,
921
15.8k
            v128_scratch: None,
922
15.8k
        }
923
15.8k
    }
924
925
5.67k
    pub fn finish(self, u: &mut Unstructured<'_>, module: &mut Module) -> arbitrary::Result<()> {
926
        // Any globals injected as part of dropping operands on the stack get
927
        // injected into the module here. Each global is then exported, most of
928
        // the time (if additional exports are allowed), to ensure it's part of
929
        // the "image" of this module available for differential execution for
930
        // example.
931
6.68k
        for (ty, init) in self.new_globals {
932
1.01k
            let global_idx = module.globals.len() as u32;
933
1.01k
            module.globals.push(GlobalType {
934
1.01k
                val_type: ty,
935
1.01k
                mutable: true,
936
1.01k
                shared: false,
937
1.01k
            });
938
1.01k
            module.defined_globals.push((global_idx, init));
939
1.01k
940
1.01k
            if self.disallow_exporting || u.ratio(1, 100).unwrap_or(false) {
941
756
                continue;
942
258
            }
943
944
258
            let name = unique_string(1_000, &mut module.export_names, u)?;
945
258
            module.add_arbitrary_export(name, ExportKind::Global, global_idx)?;
946
        }
947
5.67k
        Ok(())
948
5.67k
    }
949
}
950
951
impl CodeBuilder<'_> {
952
547
    fn pop_control(&mut self) -> Control {
953
547
        let control = self.allocs.controls.pop().unwrap();
954
955
        // Pop the actual types on the stack (which could be subtypes of the
956
        // declared types) and then push the declared types. This avoids us
957
        // accidentally generating code that relies on erased subtypes.
958
605
        for _ in &control.results {
959
58
            self.pop_operand();
960
58
        }
961
605
        for ty in &control.results {
962
58
            self.push_operand(Some(*ty));
963
58
        }
964
965
547
        control
966
547
    }
967
968
6.78k
    fn push_control(
969
6.78k
        &mut self,
970
6.78k
        kind: ControlKind,
971
6.78k
        params: impl Into<Vec<ValType>>,
972
6.78k
        results: impl Into<Vec<ValType>>,
973
6.78k
    ) {
974
6.78k
        let params = params.into();
975
6.78k
        let results = results.into();
976
977
        // Similar to in `pop_control`, we want to pop the actual argument types
978
        // off the stack (which could be subtypes of the declared parameter
979
        // types) and then push the parameter types. This effectively does type
980
        // erasure of any subtyping that exists so that we don't accidentally
981
        // generate code that relies on the specific subtypes.
982
7.03k
        for _ in &params {
983
247
            self.pop_operand();
984
247
        }
985
6.78k
        self.push_operands(&params);
986
6.78k
987
6.78k
        let height = self.allocs.operands.len() - params.len();
988
6.78k
        self.allocs.controls.push(Control {
989
6.78k
            kind,
990
6.78k
            params,
991
6.78k
            results,
992
6.78k
            height,
993
6.78k
        });
994
6.78k
    }
995
996
    /// Get the operands that are in-scope within the current control frame.
997
    #[inline]
998
19.1M
    fn operands(&self) -> &[Option<ValType>] {
999
19.1M
        let height = self.allocs.controls.last().map_or(0, |c| c.height);
1000
19.1M
        &self.allocs.operands[height..]
1001
19.1M
    }
1002
1003
    /// Pop a single operand from the stack, regardless of expected type.
1004
    #[inline]
1005
714
    fn pop_operand(&mut self) -> Option<ValType> {
1006
714
        self.allocs.operands.pop().unwrap()
1007
714
    }
1008
1009
    #[inline]
1010
51.5k
    fn pop_operands(&mut self, module: &Module, to_pop: &[ValType]) {
1011
51.5k
        debug_assert!(self.types_on_stack(module, to_pop));
1012
51.5k
        self.allocs
1013
51.5k
            .operands
1014
51.5k
            .truncate(self.allocs.operands.len() - to_pop.len());
1015
51.5k
    }
1016
1017
    #[inline]
1018
63.1k
    fn push_operands(&mut self, to_push: &[ValType]) {
1019
63.1k
        self.allocs
1020
63.1k
            .operands
1021
63.1k
            .extend(to_push.iter().copied().map(Some));
1022
63.1k
    }
1023
1024
    #[inline]
1025
1.06k
    fn push_operand(&mut self, ty: Option<ValType>) {
1026
1.06k
        self.allocs.operands.push(ty);
1027
1.06k
    }
1028
1029
3.08k
    fn pop_label_types(&mut self, module: &Module, target: u32) {
1030
3.08k
        let target = usize::try_from(target).unwrap();
1031
3.08k
        let control = &self.allocs.controls[self.allocs.controls.len() - 1 - target];
1032
3.08k
        debug_assert!(self.label_types_on_stack(module, control));
1033
3.08k
        self.allocs
1034
3.08k
            .operands
1035
3.08k
            .truncate(self.allocs.operands.len() - control.label_types().len());
1036
3.08k
    }
1037
1038
556
    fn push_label_types(&mut self, target: u32) {
1039
556
        let target = usize::try_from(target).unwrap();
1040
556
        let control = &self.allocs.controls[self.allocs.controls.len() - 1 - target];
1041
556
        self.allocs
1042
556
            .operands
1043
556
            .extend(control.label_types().iter().copied().map(Some));
1044
556
    }
1045
1046
    /// Pop the target label types, and then push them again.
1047
    ///
1048
    /// This is not a no-op due to subtyping: if we have a `T <: U` on the
1049
    /// stack, and the target label's type is `[U]`, then this will erase the
1050
    /// information about `T` and subsequent operations may only operate on `U`.
1051
556
    fn pop_push_label_types(&mut self, module: &Module, target: u32) {
1052
556
        self.pop_label_types(module, target);
1053
556
        self.push_label_types(target)
1054
556
    }
1055
1056
266k
    fn label_types_on_stack(&self, module: &Module, to_check: &Control) -> bool {
1057
266k
        self.types_on_stack(module, to_check.label_types())
1058
266k
    }
1059
1060
    /// Is the given type on top of the stack?
1061
    #[inline]
1062
1.98M
    fn type_on_stack(&self, module: &Module, ty: ValType) -> bool {
1063
1.98M
        self.type_on_stack_at(module, 0, ty)
1064
1.98M
    }
1065
1066
    /// Is the given type on the stack at the given index (indexing from the top
1067
    /// of the stack towards the bottom).
1068
    #[inline]
1069
8.12M
    fn type_on_stack_at(&self, module: &Module, at: usize, expected: ValType) -> bool {
1070
8.12M
        let operands = self.operands();
1071
8.12M
        if at >= operands.len() {
1072
356k
            return false;
1073
7.77M
        }
1074
7.77M
        match operands[operands.len() - 1 - at] {
1075
0
            None => true,
1076
7.77M
            Some(actual) => module.val_type_is_sub_type(actual, expected),
1077
        }
1078
8.12M
    }
1079
1080
    /// Are the given types on top of the stack?
1081
    #[inline]
1082
10.6M
    fn types_on_stack(&self, module: &Module, types: &[ValType]) -> bool {
1083
10.6M
        self.operands().len() >= types.len()
1084
5.78M
            && types
1085
5.78M
                .iter()
1086
5.78M
                .rev()
1087
5.78M
                .enumerate()
1088
6.13M
                .all(|(idx, ty)| self.type_on_stack_at(module, idx, *ty))
1089
10.6M
    }
1090
1091
    /// Are the given field types on top of the stack?
1092
    #[inline]
1093
0
    fn field_types_on_stack(&self, module: &Module, types: &[FieldType]) -> bool {
1094
0
        self.operands().len() >= types.len()
1095
0
            && types
1096
0
                .iter()
1097
0
                .rev()
1098
0
                .enumerate()
1099
0
                .all(|(idx, ty)| self.type_on_stack_at(module, idx, ty.element_type.unpack()))
1100
0
    }
1101
1102
    /// Is the given field type on top of the stack?
1103
    #[inline]
1104
0
    fn field_type_on_stack(&self, module: &Module, ty: FieldType) -> bool {
1105
0
        self.type_on_stack(module, ty.element_type.unpack())
1106
0
    }
1107
1108
    /// Is the given field type on the stack at the given position (indexed from
1109
    /// the top of the stack)?
1110
    #[inline]
1111
0
    fn field_type_on_stack_at(&self, module: &Module, at: usize, ty: FieldType) -> bool {
1112
0
        self.type_on_stack_at(module, at, ty.element_type.unpack())
1113
0
    }
1114
1115
    /// Get the ref type on the top of the operand stack, if any.
1116
    ///
1117
    /// * `None` means no reftype on the stack.
1118
    /// * `Some(None)` means that the stack is polymorphic.
1119
    /// * `Some(Some(r))` means that `r` is the ref type on top of the stack.
1120
162k
    fn ref_type_on_stack(&self) -> Option<Option<RefType>> {
1121
162k
        match self.operands().last().copied()? {
1122
0
            Some(ValType::Ref(r)) => Some(Some(r)),
1123
132k
            Some(_) => None,
1124
0
            None => Some(None),
1125
        }
1126
162k
    }
1127
1128
    /// Is there a `(ref null? <index>)` on the stack at the given position? If
1129
    /// so return its nullability and type index.
1130
0
    fn concrete_ref_type_on_stack_at(&self, at: usize) -> Option<(bool, u32)> {
1131
0
        match self.operands().iter().copied().rev().nth(at)?? {
1132
            ValType::Ref(RefType {
1133
0
                nullable,
1134
0
                heap_type: HeapType::Concrete(ty),
1135
0
            }) => Some((nullable, ty)),
1136
0
            _ => None,
1137
        }
1138
0
    }
1139
1140
    /// Is there a `(ref null? <index>)` at the given stack position that
1141
    /// references a concrete array type?
1142
0
    fn concrete_array_ref_type_on_stack_at(
1143
0
        &self,
1144
0
        module: &Module,
1145
0
        at: usize,
1146
0
    ) -> Option<(bool, u32, ArrayType)> {
1147
0
        let (nullable, ty) = self.concrete_ref_type_on_stack_at(at)?;
1148
0
        match &module.ty(ty).composite_type {
1149
0
            CompositeType::Array(a) => Some((nullable, ty, *a)),
1150
0
            _ => None,
1151
        }
1152
0
    }
1153
1154
    /// Is there a `(ref null? <index>)` at the given stack position that
1155
    /// references a concrete struct type?
1156
0
    fn concrete_struct_ref_type_on_stack_at<'a>(
1157
0
        &self,
1158
0
        module: &'a Module,
1159
0
        at: usize,
1160
0
    ) -> Option<(bool, u32, &'a StructType)> {
1161
0
        let (nullable, ty) = self.concrete_ref_type_on_stack_at(at)?;
1162
0
        match &module.ty(ty).composite_type {
1163
0
            CompositeType::Struct(s) => Some((nullable, ty, s)),
1164
0
            _ => None,
1165
        }
1166
0
    }
1167
1168
    /// Pop a reference type from the stack and return it.
1169
    ///
1170
    /// When in unreachable code and the stack is polymorphic, returns `None`.
1171
0
    fn pop_ref_type(&mut self) -> Option<RefType> {
1172
0
        let ref_ty = self.ref_type_on_stack().unwrap();
1173
0
        self.pop_operand();
1174
0
        ref_ty
1175
0
    }
1176
1177
    /// Pops a `(ref null? <index>)` from the stack and return its nullability
1178
    /// and type index.
1179
0
    fn pop_concrete_ref_type(&mut self) -> (bool, u32) {
1180
0
        let ref_ty = self.pop_ref_type().unwrap();
1181
0
        match ref_ty.heap_type {
1182
0
            HeapType::Concrete(i) => (ref_ty.nullable, i),
1183
0
            _ => panic!("not a concrete ref type"),
1184
        }
1185
0
    }
1186
1187
    /// Get the `(ref null? <index>)` type on the top of the stack that
1188
    /// references a function type, if any.
1189
0
    fn concrete_funcref_on_stack(&self, module: &Module) -> Option<RefType> {
1190
0
        match self.operands().last().copied()?? {
1191
0
            ValType::Ref(r) => match r.heap_type {
1192
0
                HeapType::Concrete(idx) => match &module.ty(idx).composite_type {
1193
0
                    CompositeType::Func(_) => Some(r),
1194
0
                    CompositeType::Struct(_) | CompositeType::Array(_) => None,
1195
                },
1196
0
                _ => None,
1197
            },
1198
0
            _ => None,
1199
        }
1200
0
    }
1201
1202
    /// Is there a `(ref null? <index>)` on the top of the stack that references
1203
    /// a struct type with at least one field?
1204
0
    fn non_empty_struct_ref_on_stack(&self, module: &Module, allow_null_refs: bool) -> bool {
1205
0
        match self.operands().last() {
1206
            Some(Some(ValType::Ref(RefType {
1207
0
                nullable,
1208
0
                heap_type: HeapType::Concrete(idx),
1209
0
            }))) => match &module.ty(*idx).composite_type {
1210
0
                CompositeType::Struct(s) => !s.fields.is_empty() && (!nullable || allow_null_refs),
1211
0
                _ => false,
1212
            },
1213
0
            _ => false,
1214
        }
1215
0
    }
1216
1217
    #[inline(never)]
1218
6.68k
    fn arbitrary_block_type(&self, u: &mut Unstructured, module: &Module) -> Result<BlockType> {
1219
6.68k
        let mut options: Vec<Box<dyn Fn(&mut Unstructured) -> Result<BlockType>>> = vec![
1220
6.68k
            Box::new(|_| Ok(BlockType::Empty)),
1221
6.68k
            Box::new(|u| Ok(BlockType::Result(module.arbitrary_valtype(u)?))),
1222
6.68k
        ];
1223
6.68k
        if module.config.multi_value_enabled {
1224
8.13k
            for (i, ty) in module.func_types() {
1225
8.13k
                if self.types_on_stack(module, &ty.params) {
1226
7.27k
                    options.push(Box::new(move |_| Ok(BlockType::FunctionType(i as u32))));
1227
7.27k
                }
1228
            }
1229
0
        }
1230
6.68k
        let f = u.choose(&options)?;
1231
6.68k
        f(u)
1232
6.68k
    }
1233
1234
15.8k
    pub(crate) fn arbitrary(
1235
15.8k
        mut self,
1236
15.8k
        u: &mut Unstructured,
1237
15.8k
        module: &Module,
1238
15.8k
    ) -> Result<Vec<Instruction>> {
1239
15.8k
        let max_instructions = module.config.max_instructions;
1240
15.8k
        let allowed_instructions = module.config.allowed_instructions;
1241
15.8k
        let mut instructions = vec![];
1242
1243
97.0k
        while !self.allocs.controls.is_empty() {
1244
97.0k
            let keep_going = instructions.len() < max_instructions && u.arbitrary::<u8>()? != 0;
1245
97.0k
            if !keep_going {
1246
15.8k
                self.end_active_control_frames(
1247
15.8k
                    u,
1248
15.8k
                    module,
1249
15.8k
                    &mut instructions,
1250
15.8k
                    module.config.disallow_traps,
1251
15.8k
                )?;
1252
15.8k
                break;
1253
81.2k
            }
1254
81.2k
1255
81.2k
            match choose_instruction(u, module, allowed_instructions, &mut self) {
1256
81.2k
                Some(f) => {
1257
81.2k
                    f(u, module, &mut self, &mut instructions)?;
1258
                }
1259
                // Choosing an instruction can fail because there is not enough
1260
                // underlying data, so we really cannot generate any more
1261
                // instructions. In this case we swallow that error and instead
1262
                // just terminate our wasm function's frames.
1263
                None => {
1264
0
                    self.end_active_control_frames(
1265
0
                        u,
1266
0
                        module,
1267
0
                        &mut instructions,
1268
0
                        module.config.disallow_traps,
1269
0
                    )?;
1270
0
                    break;
1271
                }
1272
            }
1273
1274
            // If the configuration for this module requests nan
1275
            // canonicalization then perform that here based on whether or not
1276
            // the previous instruction needs canonicalization. Note that this
1277
            // is based off Cranelift's pass for nan canonicalization for which
1278
            // instructions to canonicalize, but the general idea is most
1279
            // floating-point operations.
1280
81.2k
            if module.config.canonicalize_nans {
1281
0
                match instructions.last().unwrap() {
1282
0
                    Instruction::F32Ceil
1283
0
                    | Instruction::F32Floor
1284
0
                    | Instruction::F32Nearest
1285
0
                    | Instruction::F32Sqrt
1286
0
                    | Instruction::F32Trunc
1287
0
                    | Instruction::F32Div
1288
0
                    | Instruction::F32Max
1289
0
                    | Instruction::F32Min
1290
0
                    | Instruction::F32Mul
1291
0
                    | Instruction::F32Sub
1292
0
                    | Instruction::F32Add => self.canonicalize_nan(Float::F32, &mut instructions),
1293
0
                    Instruction::F64Ceil
1294
0
                    | Instruction::F64Floor
1295
0
                    | Instruction::F64Nearest
1296
0
                    | Instruction::F64Sqrt
1297
0
                    | Instruction::F64Trunc
1298
0
                    | Instruction::F64Div
1299
0
                    | Instruction::F64Max
1300
0
                    | Instruction::F64Min
1301
0
                    | Instruction::F64Mul
1302
0
                    | Instruction::F64Sub
1303
0
                    | Instruction::F64Add => self.canonicalize_nan(Float::F64, &mut instructions),
1304
0
                    Instruction::F32x4Ceil
1305
0
                    | Instruction::F32x4Floor
1306
0
                    | Instruction::F32x4Nearest
1307
0
                    | Instruction::F32x4Sqrt
1308
0
                    | Instruction::F32x4Trunc
1309
0
                    | Instruction::F32x4Div
1310
0
                    | Instruction::F32x4Max
1311
0
                    | Instruction::F32x4Min
1312
0
                    | Instruction::F32x4Mul
1313
0
                    | Instruction::F32x4Sub
1314
0
                    | Instruction::F32x4Add => {
1315
0
                        self.canonicalize_nan(Float::F32x4, &mut instructions)
1316
                    }
1317
0
                    Instruction::F64x2Ceil
1318
0
                    | Instruction::F64x2Floor
1319
0
                    | Instruction::F64x2Nearest
1320
0
                    | Instruction::F64x2Sqrt
1321
0
                    | Instruction::F64x2Trunc
1322
0
                    | Instruction::F64x2Div
1323
0
                    | Instruction::F64x2Max
1324
0
                    | Instruction::F64x2Min
1325
0
                    | Instruction::F64x2Mul
1326
0
                    | Instruction::F64x2Sub
1327
0
                    | Instruction::F64x2Add => {
1328
0
                        self.canonicalize_nan(Float::F64x2, &mut instructions)
1329
                    }
1330
0
                    _ => {}
1331
                }
1332
81.2k
            }
1333
        }
1334
1335
15.8k
        self.locals.extend(self.extra_locals.drain(..));
1336
15.8k
1337
15.8k
        Ok(instructions)
1338
15.8k
    }
1339
1340
0
    fn canonicalize_nan(&mut self, ty: Float, ins: &mut Vec<Instruction>) {
1341
        // We'll need to temporarily save the top of the stack into a local, so
1342
        // figure out that local here. Note that this tries to use the same
1343
        // local if canonicalization happens more than once in a function.
1344
0
        let (local, val_ty) = match ty {
1345
0
            Float::F32 => (&mut self.f32_scratch, ValType::F32),
1346
0
            Float::F64 => (&mut self.f64_scratch, ValType::F64),
1347
0
            Float::F32x4 | Float::F64x2 => (&mut self.v128_scratch, ValType::V128),
1348
        };
1349
0
        let local = match *local {
1350
0
            Some(i) => i as u32,
1351
0
            None => self.alloc_local(val_ty),
1352
        };
1353
1354
        // Save the previous instruction's result into a local. This also leaves
1355
        // a value on the stack as `val1` for the `select` instruction.
1356
0
        ins.push(Instruction::LocalTee(local));
1357
0
1358
0
        // The `val2` value input to the `select` below, our nan pattern.
1359
0
        //
1360
0
        // The nan patterns here are chosen to be a canonical representation
1361
0
        // which is still NaN but the wasm will always produce the same bits of
1362
0
        // a nan so if the wasm takes a look at the nan inside it'll always see
1363
0
        // the same representation.
1364
0
        const CANON_32BIT_NAN: u32 = 0b01111111110000000000000000000000;
1365
0
        const CANON_64BIT_NAN: u64 =
1366
0
            0b0111111111111000000000000000000000000000000000000000000000000000;
1367
0
        ins.push(match ty {
1368
0
            Float::F32 => Instruction::F32Const(f32::from_bits(CANON_32BIT_NAN)),
1369
0
            Float::F64 => Instruction::F64Const(f64::from_bits(CANON_64BIT_NAN)),
1370
            Float::F32x4 => {
1371
0
                let nan = CANON_32BIT_NAN as i128;
1372
0
                let nan = nan | (nan << 32) | (nan << 64) | (nan << 96);
1373
0
                Instruction::V128Const(nan)
1374
            }
1375
            Float::F64x2 => {
1376
0
                let nan = CANON_64BIT_NAN as i128;
1377
0
                let nan = nan | (nan << 64);
1378
0
                Instruction::V128Const(nan)
1379
            }
1380
        });
1381
1382
        // the condition of the `select`, which is the float's equality test
1383
        // with itself.
1384
0
        ins.push(Instruction::LocalGet(local));
1385
0
        ins.push(Instruction::LocalGet(local));
1386
0
        ins.push(match ty {
1387
0
            Float::F32 => Instruction::F32Eq,
1388
0
            Float::F64 => Instruction::F64Eq,
1389
0
            Float::F32x4 => Instruction::F32x4Eq,
1390
0
            Float::F64x2 => Instruction::F64x2Eq,
1391
        });
1392
1393
        // Select the result. If the condition is nonzero (aka the float is
1394
        // equal to itself) it picks `val1`, otherwise if zero (aka the float
1395
        // is nan) it picks `val2`.
1396
0
        ins.push(match ty {
1397
0
            Float::F32 | Float::F64 => Instruction::Select,
1398
0
            Float::F32x4 | Float::F64x2 => Instruction::V128Bitselect,
1399
        });
1400
0
    }
1401
1402
0
    fn alloc_local(&mut self, ty: ValType) -> u32 {
1403
0
        let val = self.locals.len() + self.func_ty.params.len() + self.extra_locals.len();
1404
0
        self.extra_locals.push(ty);
1405
0
        u32::try_from(val).unwrap()
1406
0
    }
1407
1408
15.8k
    fn end_active_control_frames(
1409
15.8k
        &mut self,
1410
15.8k
        u: &mut Unstructured<'_>,
1411
15.8k
        module: &Module,
1412
15.8k
        instructions: &mut Vec<Instruction>,
1413
15.8k
        disallow_traps: bool,
1414
15.8k
    ) -> Result<()> {
1415
37.8k
        while !self.allocs.controls.is_empty() {
1416
            // Ensure that this label is valid by placing the right types onto
1417
            // the operand stack for the end of the label.
1418
22.0k
            self.guarantee_label_results(u, module, instructions, disallow_traps)?;
1419
1420
            // Remove the label and clear the operand stack since the label has
1421
            // been removed.
1422
22.0k
            let label = self.allocs.controls.pop().unwrap();
1423
22.0k
            self.allocs.operands.truncate(label.height);
1424
22.0k
1425
22.0k
            // If this is an `if` that is not stack neutral, then it
1426
22.0k
            // must have an `else`. Generate synthetic results here in the same
1427
22.0k
            // manner we did above.
1428
22.0k
            if label.kind == ControlKind::If && label.params != label.results {
1429
183
                instructions.push(Instruction::Else);
1430
183
                self.allocs.controls.push(label.clone());
1431
183
                self.allocs
1432
183
                    .operands
1433
183
                    .extend(label.params.into_iter().map(Some));
1434
183
                self.guarantee_label_results(u, module, instructions, disallow_traps)?;
1435
183
                self.allocs.controls.pop();
1436
183
                self.allocs.operands.truncate(label.height);
1437
21.8k
            }
1438
1439
            // The last control frame for the function return does not
1440
            // need an `end` instruction.
1441
22.0k
            if !self.allocs.controls.is_empty() {
1442
6.23k
                instructions.push(Instruction::End);
1443
15.8k
            }
1444
1445
            // Place the results of the label onto the operand stack for use
1446
            // after the label.
1447
22.0k
            self.allocs
1448
22.0k
                .operands
1449
22.0k
                .extend(label.results.into_iter().map(Some));
1450
        }
1451
15.8k
        Ok(())
1452
15.8k
    }
1453
1454
    /// Modifies the instruction stream to guarantee that the current control
1455
    /// label's results are on the stack and ready for the control label to return.
1456
22.2k
    fn guarantee_label_results(
1457
22.2k
        &mut self,
1458
22.2k
        u: &mut Unstructured<'_>,
1459
22.2k
        module: &Module,
1460
22.2k
        instructions: &mut Vec<Instruction>,
1461
22.2k
        disallow_traps: bool,
1462
22.2k
    ) -> Result<()> {
1463
22.2k
        let operands = self.operands();
1464
22.2k
        let label = self.allocs.controls.last().unwrap();
1465
22.2k
1466
22.2k
        // Already done, yay!
1467
22.2k
        if label.results.len() == operands.len() && self.types_on_stack(module, &label.results) {
1468
12.4k
            return Ok(());
1469
9.80k
        }
1470
9.80k
1471
9.80k
        // Generating an unreachable instruction is always a valid way to
1472
9.80k
        // generate any types for a label, but it's not too interesting, so
1473
9.80k
        // don't favor it.
1474
9.80k
        if !disallow_traps && u.ratio(1, u16::MAX)? {
1475
8.43k
            instructions.push(Instruction::Unreachable);
1476
8.43k
            return Ok(());
1477
1.36k
        }
1478
1.36k
1479
1.36k
        // Arbitrarily massage the stack to get the expected results. First we
1480
1.36k
        // drop all extraneous results to we're only dealing with those we want
1481
1.36k
        // to deal with. Afterwards we start at the bottom of the stack and move
1482
1.36k
        // up, figuring out what matches and what doesn't. As soon as something
1483
1.36k
        // doesn't match we throw out that and everything else remaining,
1484
1.36k
        // filling in results with dummy values.
1485
1.36k
        let operands = operands.to_vec();
1486
1.36k
        let mut operands = operands.as_slice();
1487
1.36k
        let label_results = label.results.to_vec();
1488
5.01k
        while operands.len() > label_results.len() {
1489
3.65k
            self.drop_operand(u, *operands.last().unwrap(), instructions)?;
1490
3.65k
            operands = &operands[..operands.len() - 1];
1491
        }
1492
1.99k
        for (i, expected) in label_results.iter().enumerate() {
1493
1.99k
            if let Some(actual) = operands.get(i) {
1494
733
                if Some(*expected) == *actual {
1495
408
                    continue;
1496
325
                }
1497
586
                for ty in operands[i..].iter().rev() {
1498
586
                    self.drop_operand(u, *ty, instructions)?;
1499
                }
1500
325
                operands = &[];
1501
1.25k
            }
1502
1.58k
            instructions.push(module.arbitrary_const_instruction(*expected, u)?);
1503
        }
1504
1.36k
        Ok(())
1505
22.2k
    }
1506
1507
4.29k
    fn drop_operand(
1508
4.29k
        &mut self,
1509
4.29k
        u: &mut Unstructured<'_>,
1510
4.29k
        ty: Option<ValType>,
1511
4.29k
        instructions: &mut Vec<Instruction>,
1512
4.29k
    ) -> Result<()> {
1513
4.29k
        if !self.mix_operand_into_global(u, ty, instructions)? {
1514
1.25k
            instructions.push(Instruction::Drop);
1515
3.04k
        }
1516
4.29k
        Ok(())
1517
4.29k
    }
1518
1519
    /// Attempts to drop the top operand on the stack by "mixing" it into a
1520
    /// global.
1521
    ///
1522
    /// This is done to avoid dropping values on the floor to ensure that
1523
    /// everything is part of some computation somewhere. Otherwise, for
1524
    /// example, most function results are dropped on the floor as the stack
1525
    /// won't happen to match the function type that we're generating.
1526
    ///
1527
    /// This will return `true` if the operand has been dropped, and `false` if
1528
    /// it didn't for one reason or another.
1529
4.29k
    fn mix_operand_into_global(
1530
4.29k
        &mut self,
1531
4.29k
        u: &mut Unstructured<'_>,
1532
4.29k
        ty: Option<ValType>,
1533
4.29k
        instructions: &mut Vec<Instruction>,
1534
4.29k
    ) -> Result<bool> {
1535
        // If the type of this operand isn't known, for example if it's relevant
1536
        // to unreachable code, then it can't be combined, so return `false`.
1537
4.29k
        let ty = match ty {
1538
4.29k
            Some(ty) => ty,
1539
0
            None => return Ok(false),
1540
        };
1541
1542
        // Use the input stream to allow a small chance of dropping the value
1543
        // without combining it.
1544
4.29k
        if u.ratio(1, 100)? {
1545
1.25k
            return Ok(false);
1546
3.04k
        }
1547
1548
        // Depending on the type lookup or inject a global to place this value
1549
        // into.
1550
3.04k
        let (global, combine) = match ty {
1551
            ValType::I32 => {
1552
952
                let global = *self.allocs.global_dropped_i32.get_or_insert_with(|| {
1553
334
                    self.allocs.new_globals.push((ty, ConstExpr::i32_const(0)));
1554
334
                    inc(&mut self.allocs.globals_cnt)
1555
952
                });
1556
952
                (global, Instruction::I32Xor)
1557
            }
1558
            ValType::I64 => {
1559
583
                let global = *self.allocs.global_dropped_i64.get_or_insert_with(|| {
1560
251
                    self.allocs.new_globals.push((ty, ConstExpr::i64_const(0)));
1561
251
                    inc(&mut self.allocs.globals_cnt)
1562
583
                });
1563
583
                (global, Instruction::I64Xor)
1564
            }
1565
            ValType::F32 => {
1566
1.10k
                let global = *self.allocs.global_dropped_f32.get_or_insert_with(|| {
1567
233
                    self.allocs
1568
233
                        .new_globals
1569
233
                        .push((ValType::I32, ConstExpr::i32_const(0)));
1570
233
                    inc(&mut self.allocs.globals_cnt)
1571
1.10k
                });
1572
1.10k
                instructions.push(Instruction::I32ReinterpretF32);
1573
1.10k
                (global, Instruction::I32Xor)
1574
            }
1575
            ValType::F64 => {
1576
403
                let global = *self.allocs.global_dropped_f64.get_or_insert_with(|| {
1577
196
                    self.allocs
1578
196
                        .new_globals
1579
196
                        .push((ValType::I64, ConstExpr::i64_const(0)));
1580
196
                    inc(&mut self.allocs.globals_cnt)
1581
403
                });
1582
403
                instructions.push(Instruction::I64ReinterpretF64);
1583
403
                (global, Instruction::I64Xor)
1584
            }
1585
            ValType::V128 => {
1586
0
                let global = *self.allocs.global_dropped_v128.get_or_insert_with(|| {
1587
0
                    self.allocs.new_globals.push((ty, ConstExpr::v128_const(0)));
1588
0
                    inc(&mut self.allocs.globals_cnt)
1589
0
                });
1590
0
                (global, Instruction::V128Xor)
1591
            }
1592
1593
            // Don't know how to combine reference types at this time, so just
1594
            // let it get dropped.
1595
0
            ValType::Ref(_) => return Ok(false),
1596
        };
1597
3.04k
        instructions.push(Instruction::GlobalGet(global));
1598
3.04k
        instructions.push(combine);
1599
3.04k
        instructions.push(Instruction::GlobalSet(global));
1600
3.04k
1601
3.04k
        return Ok(true);
1602
1603
1.01k
        fn inc(val: &mut u32) -> u32 {
1604
1.01k
            let ret = *val;
1605
1.01k
            *val += 1;
1606
1.01k
            ret
1607
1.01k
        }
1608
4.29k
    }
1609
}
1610
1611
#[inline]
1612
81.2k
fn unreachable_valid(module: &Module, _: &mut CodeBuilder) -> bool {
1613
81.2k
    !module.config.disallow_traps
1614
81.2k
}
1615
1616
1.47k
fn unreachable(
1617
1.47k
    _: &mut Unstructured,
1618
1.47k
    _: &Module,
1619
1.47k
    _: &mut CodeBuilder,
1620
1.47k
    instructions: &mut Vec<Instruction>,
1621
1.47k
) -> Result<()> {
1622
1.47k
    instructions.push(Instruction::Unreachable);
1623
1.47k
    Ok(())
1624
1.47k
}
1625
1626
1.70k
fn nop(
1627
1.70k
    _: &mut Unstructured,
1628
1.70k
    _: &Module,
1629
1.70k
    _: &mut CodeBuilder,
1630
1.70k
    instructions: &mut Vec<Instruction>,
1631
1.70k
) -> Result<()> {
1632
1.70k
    instructions.push(Instruction::Nop);
1633
1.70k
    Ok(())
1634
1.70k
}
1635
1636
4.04k
fn block(
1637
4.04k
    u: &mut Unstructured,
1638
4.04k
    module: &Module,
1639
4.04k
    builder: &mut CodeBuilder,
1640
4.04k
    instructions: &mut Vec<Instruction>,
1641
4.04k
) -> Result<()> {
1642
4.04k
    let block_ty = builder.arbitrary_block_type(u, module)?;
1643
4.04k
    let (params, results) = module.params_results(&block_ty);
1644
4.04k
    builder.push_control(ControlKind::Block, params, results);
1645
4.04k
    instructions.push(Instruction::Block(block_ty));
1646
4.04k
    Ok(())
1647
4.04k
}
1648
1649
#[inline]
1650
81.2k
fn try_table_valid(module: &Module, _: &mut CodeBuilder) -> bool {
1651
81.2k
    module.config.exceptions_enabled
1652
81.2k
}
1653
1654
0
fn try_table(
1655
0
    u: &mut Unstructured,
1656
0
    module: &Module,
1657
0
    builder: &mut CodeBuilder,
1658
0
    instructions: &mut Vec<Instruction>,
1659
0
) -> Result<()> {
1660
0
    let block_ty = builder.arbitrary_block_type(u, module)?;
1661
1662
0
    let mut catch_options: Vec<
1663
0
        Box<dyn Fn(&mut Unstructured<'_>, &mut CodeBuilder<'_>) -> Result<Catch>>,
1664
0
    > = Vec::new();
1665
1666
0
    for (i, ctrl) in builder.allocs.controls.iter().rev().enumerate() {
1667
0
        let i = i as u32;
1668
0
1669
0
        let label_types = ctrl.label_types();
1670
0
1671
0
        // Empty labels are candidates for a `catch_all` since nothing is
1672
0
        // pushed in that case.
1673
0
        if label_types.is_empty() {
1674
0
            catch_options.push(Box::new(move |_, _| Ok(Catch::All { label: i })));
1675
0
        }
1676
1677
        // Labels with just an `externref` are suitable for `catch_all_refs`,
1678
        // which first pushes nothing since there's no tag and then pushes
1679
        // the caught exception value.
1680
0
        if label_types == [ValType::EXNREF] {
1681
0
            catch_options.push(Box::new(move |_, _| Ok(Catch::AllRef { label: i })));
1682
0
        }
1683
1684
        // If there is a tag which exactly matches the types of the label we're
1685
        // looking at then that tag can be used as part of a `catch` branch.
1686
        // That tag's parameters, which are the except values, are pushed
1687
        // for the label.
1688
0
        if builder.allocs.tags.contains_key(label_types) {
1689
0
            let label_types = label_types.to_vec();
1690
0
            catch_options.push(Box::new(move |u, builder| {
1691
0
                Ok(Catch::One {
1692
0
                    tag: *u.choose(&builder.allocs.tags[&label_types])?,
1693
0
                    label: i,
1694
                })
1695
0
            }));
1696
0
        }
1697
1698
        // And finally the last type of catch label, `catch_ref`. If the label
1699
        // ends with `exnref`, then use everything except the last `exnref` to
1700
        // see if there's a matching tag. If so then `catch_ref` can be used
1701
        // with that tag when branching to this label.
1702
0
        if let Some((&ValType::EXNREF, rest)) = label_types.split_last() {
1703
0
            if builder.allocs.tags.contains_key(rest) {
1704
0
                let rest = rest.to_vec();
1705
0
                catch_options.push(Box::new(move |u, builder| {
1706
0
                    Ok(Catch::OneRef {
1707
0
                        tag: *u.choose(&builder.allocs.tags[&rest])?,
1708
0
                        label: i,
1709
                    })
1710
0
                }));
1711
0
            }
1712
0
        }
1713
    }
1714
1715
0
    let mut catches = Vec::new();
1716
0
    if catch_options.len() > 0 {
1717
0
        for _ in 0..u.int_in_range(0..=10)? {
1718
0
            catches.push(u.choose(&mut catch_options)?(u, builder)?);
1719
        }
1720
0
    }
1721
1722
0
    let (params, results) = module.params_results(&block_ty);
1723
0
    builder.push_control(ControlKind::TryTable, params, results);
1724
0
1725
0
    instructions.push(Instruction::TryTable(block_ty, catches.into()));
1726
0
    Ok(())
1727
0
}
1728
1729
2.22k
fn r#loop(
1730
2.22k
    u: &mut Unstructured,
1731
2.22k
    module: &Module,
1732
2.22k
    builder: &mut CodeBuilder,
1733
2.22k
    instructions: &mut Vec<Instruction>,
1734
2.22k
) -> Result<()> {
1735
2.22k
    let block_ty = builder.arbitrary_block_type(u, module)?;
1736
2.22k
    let (params, results) = module.params_results(&block_ty);
1737
2.22k
    builder.push_control(ControlKind::Loop, params, results);
1738
2.22k
    instructions.push(Instruction::Loop(block_ty));
1739
2.22k
    Ok(())
1740
2.22k
}
1741
1742
#[inline]
1743
81.2k
fn if_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1744
81.2k
    builder.type_on_stack(module, ValType::I32)
1745
81.2k
}
1746
1747
411
fn r#if(
1748
411
    u: &mut Unstructured,
1749
411
    module: &Module,
1750
411
    builder: &mut CodeBuilder,
1751
411
    instructions: &mut Vec<Instruction>,
1752
411
) -> Result<()> {
1753
411
    builder.pop_operands(module, &[ValType::I32]);
1754
411
    let block_ty = builder.arbitrary_block_type(u, module)?;
1755
411
    let (params, results) = module.params_results(&block_ty);
1756
411
    builder.push_control(ControlKind::If, params, results);
1757
411
    instructions.push(Instruction::If(block_ty));
1758
411
    Ok(())
1759
411
}
1760
1761
#[inline]
1762
81.2k
fn else_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1763
81.2k
    let last_control = builder.allocs.controls.last().unwrap();
1764
81.2k
    last_control.kind == ControlKind::If
1765
1.46k
        && builder.operands().len() == last_control.results.len()
1766
657
        && builder.types_on_stack(module, &last_control.results)
1767
81.2k
}
1768
1769
105
fn r#else(
1770
105
    _: &mut Unstructured,
1771
105
    module: &Module,
1772
105
    builder: &mut CodeBuilder,
1773
105
    instructions: &mut Vec<Instruction>,
1774
105
) -> Result<()> {
1775
105
    let control = builder.pop_control();
1776
105
    builder.pop_operands(module, &control.results);
1777
105
    builder.push_operands(&control.params);
1778
105
    builder.push_control(ControlKind::Block, control.params, control.results);
1779
105
    instructions.push(Instruction::Else);
1780
105
    Ok(())
1781
105
}
1782
1783
#[inline]
1784
81.2k
fn end_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1785
81.2k
    // Note: first control frame is the function return's control frame, which
1786
81.2k
    // does not have an associated `end`.
1787
81.2k
    if builder.allocs.controls.len() <= 1 {
1788
51.5k
        return false;
1789
29.7k
    }
1790
29.7k
    let control = builder.allocs.controls.last().unwrap();
1791
29.7k
    builder.operands().len() == control.results.len()
1792
11.0k
        && builder.types_on_stack(module, &control.results)
1793
        // `if`s that don't leave the stack as they found it must have an
1794
        // `else`.
1795
7.39k
        && !(control.kind == ControlKind::If && control.params != control.results)
1796
81.2k
}
1797
1798
442
fn end(
1799
442
    _: &mut Unstructured,
1800
442
    _: &Module,
1801
442
    builder: &mut CodeBuilder,
1802
442
    instructions: &mut Vec<Instruction>,
1803
442
) -> Result<()> {
1804
442
    builder.pop_control();
1805
442
    instructions.push(Instruction::End);
1806
442
    Ok(())
1807
442
}
1808
1809
#[inline]
1810
106k
fn br_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1811
106k
    builder
1812
106k
        .allocs
1813
106k
        .controls
1814
106k
        .iter()
1815
129k
        .any(|l| builder.label_types_on_stack(module, l))
1816
106k
}
1817
1818
2.53k
fn br(
1819
2.53k
    u: &mut Unstructured,
1820
2.53k
    module: &Module,
1821
2.53k
    builder: &mut CodeBuilder,
1822
2.53k
    instructions: &mut Vec<Instruction>,
1823
2.53k
) -> Result<()> {
1824
2.53k
    let n = builder
1825
2.53k
        .allocs
1826
2.53k
        .controls
1827
2.53k
        .iter()
1828
8.37k
        .filter(|l| builder.label_types_on_stack(module, l))
1829
2.53k
        .count();
1830
2.53k
    debug_assert!(n > 0);
1831
2.53k
    let i = u.int_in_range(0..=n - 1)?;
1832
2.53k
    let (target, _) = builder
1833
2.53k
        .allocs
1834
2.53k
        .controls
1835
2.53k
        .iter()
1836
2.53k
        .rev()
1837
2.53k
        .enumerate()
1838
5.98k
        .filter(|(_, l)| builder.label_types_on_stack(module, l))
1839
2.53k
        .nth(i)
1840
2.53k
        .unwrap();
1841
2.53k
    let target = u32::try_from(target).unwrap();
1842
2.53k
    builder.pop_label_types(module, target);
1843
2.53k
    instructions.push(Instruction::Br(target));
1844
2.53k
    Ok(())
1845
2.53k
}
1846
1847
#[inline]
1848
81.2k
fn br_if_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1849
81.2k
    if !builder.type_on_stack(module, ValType::I32) {
1850
56.0k
        return false;
1851
25.2k
    }
1852
25.2k
    let ty = builder.allocs.operands.pop().unwrap();
1853
25.2k
    let is_valid = builder
1854
25.2k
        .allocs
1855
25.2k
        .controls
1856
25.2k
        .iter()
1857
30.6k
        .any(|l| builder.label_types_on_stack(module, l));
1858
25.2k
    builder.allocs.operands.push(ty);
1859
25.2k
    is_valid
1860
81.2k
}
1861
1862
556
fn br_if(
1863
556
    u: &mut Unstructured,
1864
556
    module: &Module,
1865
556
    builder: &mut CodeBuilder,
1866
556
    instructions: &mut Vec<Instruction>,
1867
556
) -> Result<()> {
1868
556
    builder.pop_operands(module, &[ValType::I32]);
1869
556
1870
556
    let n = builder
1871
556
        .allocs
1872
556
        .controls
1873
556
        .iter()
1874
1.29k
        .filter(|l| builder.label_types_on_stack(module, l))
1875
556
        .count();
1876
556
    debug_assert!(n > 0);
1877
556
    let i = u.int_in_range(0..=n - 1)?;
1878
556
    let (target, _) = builder
1879
556
        .allocs
1880
556
        .controls
1881
556
        .iter()
1882
556
        .rev()
1883
556
        .enumerate()
1884
1.02k
        .filter(|(_, l)| builder.label_types_on_stack(module, l))
1885
556
        .nth(i)
1886
556
        .unwrap();
1887
556
    let target = u32::try_from(target).unwrap();
1888
556
    builder.pop_push_label_types(module, target);
1889
556
    instructions.push(Instruction::BrIf(target));
1890
556
    Ok(())
1891
556
}
1892
1893
#[inline]
1894
81.2k
fn br_table_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1895
81.2k
    if !builder.type_on_stack(module, ValType::I32) {
1896
56.0k
        return false;
1897
25.2k
    }
1898
25.2k
    let ty = builder.allocs.operands.pop().unwrap();
1899
25.2k
    let is_valid = br_valid(module, builder);
1900
25.2k
    builder.allocs.operands.push(ty);
1901
25.2k
    is_valid
1902
81.2k
}
1903
1904
726
fn br_table(
1905
726
    u: &mut Unstructured,
1906
726
    module: &Module,
1907
726
    builder: &mut CodeBuilder,
1908
726
    instructions: &mut Vec<Instruction>,
1909
726
) -> Result<()> {
1910
726
    builder.pop_operands(module, &[ValType::I32]);
1911
726
1912
726
    let n = builder
1913
726
        .allocs
1914
726
        .controls
1915
726
        .iter()
1916
3.14k
        .filter(|l| builder.label_types_on_stack(module, l))
1917
726
        .count();
1918
726
    debug_assert!(n > 0);
1919
1920
726
    let i = u.int_in_range(0..=n - 1)?;
1921
726
    let (default_target, _) = builder
1922
726
        .allocs
1923
726
        .controls
1924
726
        .iter()
1925
726
        .rev()
1926
726
        .enumerate()
1927
2.01k
        .filter(|(_, l)| builder.label_types_on_stack(module, l))
1928
726
        .nth(i)
1929
726
        .unwrap();
1930
726
    let control = &builder.allocs.controls[builder.allocs.controls.len() - 1 - default_target];
1931
726
1932
726
    let targets = builder
1933
726
        .allocs
1934
726
        .controls
1935
726
        .iter()
1936
726
        .rev()
1937
726
        .enumerate()
1938
3.14k
        .filter(|(_, l)| l.label_types() == control.label_types())
1939
2.47k
        .map(|(t, _)| t as u32)
1940
726
        .collect();
1941
726
1942
726
    let tys = control.label_types().to_vec();
1943
726
    builder.pop_operands(module, &tys);
1944
726
1945
726
    instructions.push(Instruction::BrTable(targets, default_target as u32));
1946
726
    Ok(())
1947
726
}
1948
1949
#[inline]
1950
81.2k
fn return_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1951
81.2k
    builder.label_types_on_stack(module, &builder.allocs.controls[0])
1952
81.2k
}
1953
1954
465
fn r#return(
1955
465
    _: &mut Unstructured,
1956
465
    module: &Module,
1957
465
    builder: &mut CodeBuilder,
1958
465
    instructions: &mut Vec<Instruction>,
1959
465
) -> Result<()> {
1960
465
    let results = builder.allocs.controls[0].results.clone();
1961
465
    builder.pop_operands(module, &results);
1962
465
    instructions.push(Instruction::Return);
1963
465
    Ok(())
1964
465
}
1965
1966
#[inline]
1967
81.2k
fn call_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1968
81.2k
    builder
1969
81.2k
        .allocs
1970
81.2k
        .functions
1971
81.2k
        .keys()
1972
81.6k
        .any(|func_ty| builder.types_on_stack(module, &func_ty.params))
1973
81.2k
}
1974
1975
4.35k
fn call(
1976
4.35k
    u: &mut Unstructured,
1977
4.35k
    module: &Module,
1978
4.35k
    builder: &mut CodeBuilder,
1979
4.35k
    instructions: &mut Vec<Instruction>,
1980
4.35k
) -> Result<()> {
1981
4.35k
    let candidates = builder
1982
4.35k
        .allocs
1983
4.35k
        .functions
1984
4.35k
        .iter()
1985
4.81k
        .filter(|(func_ty, _)| builder.types_on_stack(module, &func_ty.params))
1986
4.56k
        .flat_map(|(_, v)| v.iter().copied())
1987
4.35k
        .collect::<Vec<_>>();
1988
4.35k
    assert!(candidates.len() > 0);
1989
4.35k
    let i = u.int_in_range(0..=candidates.len() - 1)?;
1990
4.35k
    let (func_idx, ty) = module.funcs().nth(candidates[i] as usize).unwrap();
1991
4.35k
    builder.pop_operands(module, &ty.params);
1992
4.35k
    builder.push_operands(&ty.results);
1993
4.35k
    instructions.push(Instruction::Call(func_idx as u32));
1994
4.35k
    Ok(())
1995
4.35k
}
1996
1997
#[inline]
1998
81.2k
fn call_ref_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
1999
81.2k
    if !module.config.gc_enabled {
2000
81.2k
        return false;
2001
0
    }
2002
0
    let funcref = match builder.concrete_funcref_on_stack(module) {
2003
0
        Some(f) => f,
2004
0
        None => return false,
2005
    };
2006
0
    if module.config.disallow_traps && funcref.nullable {
2007
0
        return false;
2008
0
    }
2009
0
    match funcref.heap_type {
2010
0
        HeapType::Concrete(idx) => {
2011
0
            let ty = builder.allocs.operands.pop().unwrap();
2012
0
            let params = &module.ty(idx).unwrap_func().params;
2013
0
            let valid = builder.types_on_stack(module, params);
2014
0
            builder.allocs.operands.push(ty);
2015
0
            valid
2016
        }
2017
0
        _ => unreachable!(),
2018
    }
2019
81.2k
}
2020
2021
0
fn call_ref(
2022
0
    _u: &mut Unstructured,
2023
0
    module: &Module,
2024
0
    builder: &mut CodeBuilder,
2025
0
    instructions: &mut Vec<Instruction>,
2026
0
) -> Result<()> {
2027
0
    let heap_ty = match builder.pop_operand() {
2028
0
        Some(ValType::Ref(r)) => r.heap_type,
2029
0
        _ => unreachable!(),
2030
    };
2031
0
    let idx = match heap_ty {
2032
0
        HeapType::Concrete(idx) => idx,
2033
0
        _ => unreachable!(),
2034
    };
2035
0
    let func_ty = match &module.ty(idx).composite_type {
2036
0
        CompositeType::Func(f) => f,
2037
0
        _ => unreachable!(),
2038
    };
2039
0
    builder.pop_operands(module, &func_ty.params);
2040
0
    builder.push_operands(&func_ty.results);
2041
0
    instructions.push(Instruction::CallRef(idx));
2042
0
    Ok(())
2043
0
}
2044
2045
#[inline]
2046
81.2k
fn call_indirect_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2047
81.2k
    if module.config.disallow_traps {
2048
        // We have no way to reflect, at run time, on a `funcref` in
2049
        // the `i`th slot in a table and dynamically avoid trapping
2050
        // `call_indirect`s. Therefore, we can't emit *any*
2051
        // `call_indirect` instructions if we want to avoid traps.
2052
0
        return false;
2053
81.2k
    }
2054
81.2k
    let can_call32 = builder.type_on_stack(module, ValType::I32)
2055
25.2k
        && builder.allocs.table32_with_funcref.len() > 0;
2056
81.2k
    let can_call64 = builder.type_on_stack(module, ValType::I64)
2057
14.6k
        && builder.allocs.table64_with_funcref.len() > 0;
2058
81.2k
    if !can_call32 && !can_call64 {
2059
74.0k
        return false;
2060
7.15k
    }
2061
7.15k
    let ty = builder.allocs.operands.pop().unwrap();
2062
7.15k
    let is_valid = module
2063
7.15k
        .func_types()
2064
7.31k
        .any(|(_, ty)| builder.types_on_stack(module, &ty.params));
2065
7.15k
    builder.allocs.operands.push(ty);
2066
7.15k
    is_valid
2067
81.2k
}
2068
2069
461
fn call_indirect(
2070
461
    u: &mut Unstructured,
2071
461
    module: &Module,
2072
461
    builder: &mut CodeBuilder,
2073
461
    instructions: &mut Vec<Instruction>,
2074
461
) -> Result<()> {
2075
461
    let table = select_call_indirect_table(u, module, builder)?;
2076
2077
461
    let choices = module
2078
461
        .func_types()
2079
1.16k
        .filter(|(_, ty)| builder.types_on_stack(module, &ty.params))
2080
461
        .collect::<Vec<_>>();
2081
461
    let (type_idx, ty) = u.choose(&choices)?;
2082
461
    builder.pop_operands(module, &ty.params);
2083
461
    builder.push_operands(&ty.results);
2084
461
    instructions.push(Instruction::CallIndirect {
2085
461
        ty: *type_idx as u32,
2086
461
        table,
2087
461
    });
2088
461
    Ok(())
2089
461
}
2090
2091
461
fn select_call_indirect_table(
2092
461
    u: &mut Unstructured,
2093
461
    module: &Module,
2094
461
    builder: &mut CodeBuilder,
2095
461
) -> Result<u32> {
2096
461
    let tables = if builder.type_on_stack(module, ValType::I32) {
2097
461
        builder.pop_operands(module, &[ValType::I32]);
2098
461
        &builder.allocs.table32_with_funcref
2099
    } else {
2100
0
        builder.pop_operands(module, &[ValType::I64]);
2101
0
        &builder.allocs.table64_with_funcref
2102
    };
2103
461
    Ok(*u.choose(tables)?)
2104
461
}
2105
2106
#[inline]
2107
81.2k
fn return_call_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2108
81.2k
    if !module.config.tail_call_enabled {
2109
81.2k
        return false;
2110
0
    }
2111
0
2112
0
    builder.allocs.functions.keys().any(|func_ty| {
2113
0
        builder.types_on_stack(module, &func_ty.params)
2114
0
            && builder.allocs.controls[0].label_types() == &func_ty.results
2115
0
    })
2116
81.2k
}
2117
2118
0
fn return_call(
2119
0
    u: &mut Unstructured,
2120
0
    module: &Module,
2121
0
    builder: &mut CodeBuilder,
2122
0
    instructions: &mut Vec<Instruction>,
2123
0
) -> Result<()> {
2124
0
    let candidates = builder
2125
0
        .allocs
2126
0
        .functions
2127
0
        .iter()
2128
0
        .filter(|(func_ty, _)| {
2129
0
            builder.types_on_stack(module, &func_ty.params)
2130
0
                && builder.allocs.controls[0].label_types() == &func_ty.results
2131
0
        })
2132
0
        .flat_map(|(_, v)| v.iter().copied())
2133
0
        .collect::<Vec<_>>();
2134
0
    assert!(candidates.len() > 0);
2135
0
    let i = u.int_in_range(0..=candidates.len() - 1)?;
2136
0
    let (func_idx, ty) = module.funcs().nth(candidates[i] as usize).unwrap();
2137
0
    builder.pop_operands(module, &ty.params);
2138
0
    builder.push_operands(&ty.results);
2139
0
    instructions.push(Instruction::ReturnCall(func_idx as u32));
2140
0
    Ok(())
2141
0
}
2142
2143
#[inline]
2144
81.2k
fn return_call_ref_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2145
81.2k
    if !module.config.gc_enabled {
2146
81.2k
        return false;
2147
0
    }
2148
2149
0
    let ref_ty = match builder.concrete_funcref_on_stack(module) {
2150
0
        None => return false,
2151
0
        Some(r) if r.nullable && module.config.disallow_traps => return false,
2152
0
        Some(r) => r,
2153
    };
2154
2155
0
    let idx = match ref_ty.heap_type {
2156
0
        HeapType::Concrete(idx) => idx,
2157
0
        _ => unreachable!(),
2158
    };
2159
0
    let func_ty = match &module.ty(idx).composite_type {
2160
0
        CompositeType::Func(f) => f,
2161
0
        CompositeType::Array(_) | CompositeType::Struct(_) => return false,
2162
    };
2163
2164
0
    let ty = builder.allocs.operands.pop().unwrap();
2165
0
    let valid = builder.types_on_stack(module, &func_ty.params)
2166
0
        && builder.func_ty.results == func_ty.results;
2167
0
    builder.allocs.operands.push(ty);
2168
0
    valid
2169
81.2k
}
2170
2171
0
fn return_call_ref(
2172
0
    _u: &mut Unstructured,
2173
0
    module: &Module,
2174
0
    builder: &mut CodeBuilder,
2175
0
    instructions: &mut Vec<Instruction>,
2176
0
) -> Result<()> {
2177
0
    let heap_ty = match builder.pop_operand() {
2178
0
        Some(ValType::Ref(r)) => r.heap_type,
2179
0
        _ => unreachable!(),
2180
    };
2181
0
    let idx = match heap_ty {
2182
0
        HeapType::Concrete(idx) => idx,
2183
0
        _ => unreachable!(),
2184
    };
2185
0
    let func_ty = match &module.ty(idx).composite_type {
2186
0
        CompositeType::Func(f) => f,
2187
0
        _ => unreachable!(),
2188
    };
2189
0
    builder.pop_operands(module, &func_ty.params);
2190
0
    builder.push_operands(&func_ty.results);
2191
0
    instructions.push(Instruction::ReturnCallRef(idx));
2192
0
    Ok(())
2193
0
}
2194
2195
#[inline]
2196
81.2k
fn return_call_indirect_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2197
81.2k
    if !module.config.tail_call_enabled {
2198
81.2k
        return false;
2199
0
    }
2200
0
2201
0
    call_indirect_valid(module, builder)
2202
81.2k
}
2203
2204
0
fn return_call_indirect(
2205
0
    u: &mut Unstructured,
2206
0
    module: &Module,
2207
0
    builder: &mut CodeBuilder,
2208
0
    instructions: &mut Vec<Instruction>,
2209
0
) -> Result<()> {
2210
0
    let table = select_call_indirect_table(u, module, builder)?;
2211
2212
0
    let choices = module
2213
0
        .func_types()
2214
0
        .filter(|(_, ty)| {
2215
0
            builder.types_on_stack(module, &ty.params)
2216
0
                && builder.allocs.controls[0].label_types() == &ty.results
2217
0
        })
2218
0
        .collect::<Vec<_>>();
2219
0
    let (type_idx, ty) = u.choose(&choices)?;
2220
0
    builder.pop_operands(module, &ty.params);
2221
0
    builder.push_operands(&ty.results);
2222
0
    instructions.push(Instruction::ReturnCallIndirect {
2223
0
        ty: *type_idx as u32,
2224
0
        table,
2225
0
    });
2226
0
    Ok(())
2227
0
}
2228
2229
#[inline]
2230
81.2k
fn throw_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2231
81.2k
    module.config.exceptions_enabled
2232
0
        && builder
2233
0
            .allocs
2234
0
            .tags
2235
0
            .keys()
2236
0
            .any(|k| builder.types_on_stack(module, k))
2237
81.2k
}
2238
2239
0
fn throw(
2240
0
    u: &mut Unstructured,
2241
0
    module: &Module,
2242
0
    builder: &mut CodeBuilder,
2243
0
    instructions: &mut Vec<Instruction>,
2244
0
) -> Result<()> {
2245
0
    let candidates = builder
2246
0
        .allocs
2247
0
        .tags
2248
0
        .iter()
2249
0
        .filter(|(k, _)| builder.types_on_stack(module, k))
2250
0
        .flat_map(|(_, v)| v.iter().copied())
2251
0
        .collect::<Vec<_>>();
2252
0
    assert!(candidates.len() > 0);
2253
0
    let i = u.int_in_range(0..=candidates.len() - 1)?;
2254
0
    let (tag_idx, tag_type) = module.tags().nth(candidates[i] as usize).unwrap();
2255
0
    // Tags have no results, throwing cannot return
2256
0
    assert!(tag_type.func_type.results.len() == 0);
2257
0
    builder.pop_operands(module, &tag_type.func_type.params);
2258
0
    instructions.push(Instruction::Throw(tag_idx as u32));
2259
0
    Ok(())
2260
0
}
2261
2262
#[inline]
2263
81.2k
fn throw_ref_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2264
81.2k
    module.config.exceptions_enabled && builder.types_on_stack(module, &[ValType::EXNREF])
2265
81.2k
}
2266
2267
0
fn throw_ref(
2268
0
    _u: &mut Unstructured,
2269
0
    module: &Module,
2270
0
    builder: &mut CodeBuilder,
2271
0
    instructions: &mut Vec<Instruction>,
2272
0
) -> Result<()> {
2273
0
    builder.pop_operands(module, &[ValType::EXNREF]);
2274
0
    instructions.push(Instruction::ThrowRef);
2275
0
    Ok(())
2276
0
}
2277
2278
#[inline]
2279
81.2k
fn br_on_null_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2280
81.2k
    if !module.config.gc_enabled {
2281
81.2k
        return false;
2282
0
    }
2283
0
    if builder.ref_type_on_stack().is_none() {
2284
0
        return false;
2285
0
    }
2286
0
    let ty = builder.allocs.operands.pop().unwrap();
2287
0
    let valid = br_valid(module, builder);
2288
0
    builder.allocs.operands.push(ty);
2289
0
    valid
2290
81.2k
}
2291
2292
0
fn br_on_null(
2293
0
    u: &mut Unstructured,
2294
0
    module: &Module,
2295
0
    builder: &mut CodeBuilder,
2296
0
    instructions: &mut Vec<Instruction>,
2297
0
) -> Result<()> {
2298
0
    let heap_type = match builder.pop_ref_type() {
2299
0
        Some(r) => r.heap_type,
2300
        None => {
2301
0
            if !module.types.is_empty() && u.arbitrary()? {
2302
0
                HeapType::Concrete(u.int_in_range(0..=u32::try_from(module.types.len()).unwrap())?)
2303
            } else {
2304
0
                *u.choose(&[
2305
0
                    HeapType::Func,
2306
0
                    HeapType::Extern,
2307
0
                    HeapType::Any,
2308
0
                    HeapType::None,
2309
0
                    HeapType::NoExtern,
2310
0
                    HeapType::NoFunc,
2311
0
                    HeapType::Eq,
2312
0
                    HeapType::Struct,
2313
0
                    HeapType::Array,
2314
0
                    HeapType::I31,
2315
0
                ])?
2316
            }
2317
        }
2318
    };
2319
2320
0
    let n = builder
2321
0
        .allocs
2322
0
        .controls
2323
0
        .iter()
2324
0
        .filter(|l| builder.label_types_on_stack(module, l))
2325
0
        .count();
2326
0
    debug_assert!(n > 0);
2327
2328
0
    let i = u.int_in_range(0..=n - 1)?;
2329
0
    let (target, _) = builder
2330
0
        .allocs
2331
0
        .controls
2332
0
        .iter()
2333
0
        .rev()
2334
0
        .enumerate()
2335
0
        .filter(|(_, l)| builder.label_types_on_stack(module, l))
2336
0
        .nth(i)
2337
0
        .unwrap();
2338
0
    let target = u32::try_from(target).unwrap();
2339
0
2340
0
    builder.pop_push_label_types(module, target);
2341
0
    builder.push_operands(&[ValType::Ref(RefType {
2342
0
        nullable: false,
2343
0
        heap_type,
2344
0
    })]);
2345
0
2346
0
    instructions.push(Instruction::BrOnNull(target));
2347
0
    Ok(())
2348
0
}
2349
2350
0
fn is_valid_br_on_non_null_control(
2351
0
    module: &Module,
2352
0
    control: &Control,
2353
0
    builder: &CodeBuilder,
2354
0
) -> bool {
2355
0
    let ref_ty = match control.label_types().last() {
2356
0
        Some(ValType::Ref(r)) => *r,
2357
0
        Some(_) | None => return false,
2358
    };
2359
0
    let nullable_ref_ty = RefType {
2360
0
        nullable: true,
2361
0
        ..ref_ty
2362
0
    };
2363
0
    builder.type_on_stack(module, ValType::Ref(nullable_ref_ty))
2364
0
        && control
2365
0
            .label_types()
2366
0
            .iter()
2367
0
            .rev()
2368
0
            .enumerate()
2369
0
            .skip(1)
2370
0
            .all(|(idx, ty)| builder.type_on_stack_at(module, idx, *ty))
2371
0
}
2372
2373
#[inline]
2374
81.2k
fn br_on_non_null_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2375
81.2k
    module.config.gc_enabled
2376
0
        && builder
2377
0
            .allocs
2378
0
            .controls
2379
0
            .iter()
2380
0
            .any(|l| is_valid_br_on_non_null_control(module, l, builder))
2381
81.2k
}
2382
2383
0
fn br_on_non_null(
2384
0
    u: &mut Unstructured,
2385
0
    module: &Module,
2386
0
    builder: &mut CodeBuilder,
2387
0
    instructions: &mut Vec<Instruction>,
2388
0
) -> Result<()> {
2389
0
    let n = builder
2390
0
        .allocs
2391
0
        .controls
2392
0
        .iter()
2393
0
        .filter(|l| is_valid_br_on_non_null_control(module, l, builder))
2394
0
        .count();
2395
0
    debug_assert!(n > 0);
2396
2397
0
    let i = u.int_in_range(0..=n - 1)?;
2398
0
    let (target, _) = builder
2399
0
        .allocs
2400
0
        .controls
2401
0
        .iter()
2402
0
        .rev()
2403
0
        .enumerate()
2404
0
        .filter(|(_, l)| is_valid_br_on_non_null_control(module, l, builder))
2405
0
        .nth(i)
2406
0
        .unwrap();
2407
0
    let target = u32::try_from(target).unwrap();
2408
0
2409
0
    builder.pop_push_label_types(module, target);
2410
0
    builder.pop_ref_type();
2411
0
    instructions.push(Instruction::BrOnNonNull(target));
2412
0
    Ok(())
2413
0
}
2414
2415
0
fn is_valid_br_on_cast_control(
2416
0
    module: &Module,
2417
0
    builder: &CodeBuilder,
2418
0
    control: &Control,
2419
0
    from_ref_ty: Option<RefType>,
2420
0
) -> bool {
2421
    // The last label type is a sub type of the type we are casting from...
2422
0
    let to_ref_ty = match control.label_types().last() {
2423
0
        Some(ValType::Ref(r)) => *r,
2424
0
        _ => return false,
2425
    };
2426
0
    if let Some(from_ty) = from_ref_ty {
2427
0
        if !module.ref_type_is_sub_type(to_ref_ty, from_ty) {
2428
0
            return false;
2429
0
        }
2430
0
    }
2431
    // ... and the rest of the label types are on the stack.
2432
0
    control
2433
0
        .label_types()
2434
0
        .iter()
2435
0
        .rev()
2436
0
        .enumerate()
2437
0
        .skip(1)
2438
0
        .all(|(idx, ty)| builder.type_on_stack_at(module, idx, *ty))
2439
0
}
2440
2441
#[inline]
2442
81.2k
fn br_on_cast_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2443
81.2k
    let from_ref_ty = match builder.ref_type_on_stack() {
2444
81.2k
        None => return false,
2445
0
        Some(r) => r,
2446
0
    };
2447
0
    module.config.gc_enabled
2448
0
        && builder
2449
0
            .allocs
2450
0
            .controls
2451
0
            .iter()
2452
0
            .any(|l| is_valid_br_on_cast_control(module, builder, l, from_ref_ty))
2453
81.2k
}
2454
2455
/// Compute the [type difference] between the two given ref types.
2456
///
2457
/// [type difference]: https://webassembly.github.io/gc/core/valid/conventions.html#aux-reftypediff
2458
0
fn ref_type_difference(a: RefType, b: RefType) -> RefType {
2459
0
    RefType {
2460
0
        nullable: if b.nullable { false } else { a.nullable },
2461
0
        heap_type: a.heap_type,
2462
0
    }
2463
0
}
2464
2465
0
fn br_on_cast(
2466
0
    u: &mut Unstructured,
2467
0
    module: &Module,
2468
0
    builder: &mut CodeBuilder,
2469
0
    instructions: &mut Vec<Instruction>,
2470
0
) -> Result<()> {
2471
0
    let from_ref_type = builder.ref_type_on_stack().unwrap();
2472
0
2473
0
    let n = builder
2474
0
        .allocs
2475
0
        .controls
2476
0
        .iter()
2477
0
        .filter(|l| is_valid_br_on_cast_control(module, builder, l, from_ref_type))
2478
0
        .count();
2479
0
    debug_assert!(n > 0);
2480
2481
0
    let i = u.int_in_range(0..=n - 1)?;
2482
0
    let (relative_depth, control) = builder
2483
0
        .allocs
2484
0
        .controls
2485
0
        .iter()
2486
0
        .rev()
2487
0
        .enumerate()
2488
0
        .filter(|(_, l)| is_valid_br_on_cast_control(module, builder, l, from_ref_type))
2489
0
        .nth(i)
2490
0
        .unwrap();
2491
0
    let relative_depth = u32::try_from(relative_depth).unwrap();
2492
0
2493
0
    let num_label_types = control.label_types().len();
2494
0
    let to_ref_type = match control.label_types().last() {
2495
0
        Some(ValType::Ref(r)) => *r,
2496
0
        _ => unreachable!(),
2497
    };
2498
2499
0
    let to_ref_type = module.arbitrary_matching_ref_type(u, to_ref_type)?;
2500
0
    let from_ref_type = from_ref_type.unwrap_or(to_ref_type);
2501
0
    let from_ref_type = module.arbitrary_super_type_of_ref_type(u, from_ref_type)?;
2502
2503
    // Do `pop_push_label_types` but without its debug assert that the types are
2504
    // on the stack, since we know that we have a `from_ref_type` but the label
2505
    // requires a `to_ref_type`.
2506
0
    for _ in 0..num_label_types {
2507
0
        builder.pop_operand();
2508
0
    }
2509
0
    builder.push_label_types(relative_depth);
2510
0
2511
0
    // Replace the label's `to_ref_type` with the type difference.
2512
0
    builder.pop_operand();
2513
0
    builder.push_operands(&[ValType::Ref(ref_type_difference(
2514
0
        from_ref_type,
2515
0
        to_ref_type,
2516
0
    ))]);
2517
0
2518
0
    instructions.push(Instruction::BrOnCast {
2519
0
        from_ref_type,
2520
0
        to_ref_type,
2521
0
        relative_depth,
2522
0
    });
2523
0
    Ok(())
2524
0
}
2525
2526
0
fn is_valid_br_on_cast_fail_control(
2527
0
    module: &Module,
2528
0
    builder: &CodeBuilder,
2529
0
    control: &Control,
2530
0
    from_ref_type: Option<RefType>,
2531
0
) -> bool {
2532
0
    control
2533
0
        .label_types()
2534
0
        .last()
2535
0
        .map_or(false, |label_ty| match (label_ty, from_ref_type) {
2536
0
            (ValType::Ref(label_ty), Some(from_ty)) => {
2537
0
                module.ref_type_is_sub_type(from_ty, *label_ty)
2538
            }
2539
0
            (ValType::Ref(_), None) => true,
2540
0
            _ => false,
2541
0
        })
2542
0
        && control
2543
0
            .label_types()
2544
0
            .iter()
2545
0
            .rev()
2546
0
            .enumerate()
2547
0
            .skip(1)
2548
0
            .all(|(idx, ty)| builder.type_on_stack_at(module, idx, *ty))
2549
0
}
2550
2551
#[inline]
2552
81.2k
fn br_on_cast_fail_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2553
81.2k
    let from_ref_ty = match builder.ref_type_on_stack() {
2554
81.2k
        None => return false,
2555
0
        Some(r) => r,
2556
0
    };
2557
0
    module.config.gc_enabled
2558
0
        && builder
2559
0
            .allocs
2560
0
            .controls
2561
0
            .iter()
2562
0
            .any(|l| is_valid_br_on_cast_fail_control(module, builder, l, from_ref_ty))
2563
81.2k
}
2564
2565
0
fn br_on_cast_fail(
2566
0
    u: &mut Unstructured,
2567
0
    module: &Module,
2568
0
    builder: &mut CodeBuilder,
2569
0
    instructions: &mut Vec<Instruction>,
2570
0
) -> Result<()> {
2571
0
    let from_ref_type = builder.ref_type_on_stack().unwrap();
2572
0
2573
0
    let n = builder
2574
0
        .allocs
2575
0
        .controls
2576
0
        .iter()
2577
0
        .filter(|l| is_valid_br_on_cast_fail_control(module, builder, l, from_ref_type))
2578
0
        .count();
2579
0
    debug_assert!(n > 0);
2580
2581
0
    let i = u.int_in_range(0..=n - 1)?;
2582
0
    let (relative_depth, control) = builder
2583
0
        .allocs
2584
0
        .controls
2585
0
        .iter()
2586
0
        .rev()
2587
0
        .enumerate()
2588
0
        .filter(|(_, l)| is_valid_br_on_cast_fail_control(module, builder, l, from_ref_type))
2589
0
        .nth(i)
2590
0
        .unwrap();
2591
0
    let relative_depth = u32::try_from(relative_depth).unwrap();
2592
0
2593
0
    let from_ref_type =
2594
0
        from_ref_type.unwrap_or_else(|| match control.label_types().last().unwrap() {
2595
0
            ValType::Ref(r) => *r,
2596
0
            _ => unreachable!(),
2597
0
        });
2598
0
    let to_ref_type = module.arbitrary_matching_ref_type(u, from_ref_type)?;
2599
2600
    // Pop-push the label types and then replace its last reference type with
2601
    // our `to_ref_type`.
2602
0
    builder.pop_push_label_types(module, relative_depth);
2603
0
    builder.pop_operand();
2604
0
    builder.push_operand(Some(ValType::Ref(to_ref_type)));
2605
0
2606
0
    instructions.push(Instruction::BrOnCastFail {
2607
0
        from_ref_type,
2608
0
        to_ref_type,
2609
0
        relative_depth,
2610
0
    });
2611
0
    Ok(())
2612
0
}
2613
2614
#[inline]
2615
81.2k
fn drop_valid(_module: &Module, builder: &mut CodeBuilder) -> bool {
2616
81.2k
    !builder.operands().is_empty()
2617
81.2k
}
2618
2619
61
fn drop(
2620
61
    u: &mut Unstructured,
2621
61
    _module: &Module,
2622
61
    builder: &mut CodeBuilder,
2623
61
    instructions: &mut Vec<Instruction>,
2624
61
) -> Result<()> {
2625
61
    let ty = builder.pop_operand();
2626
61
    builder.drop_operand(u, ty, instructions)?;
2627
61
    Ok(())
2628
61
}
2629
2630
#[inline]
2631
81.2k
fn select_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2632
81.2k
    if !(builder.operands().len() >= 3 && builder.type_on_stack(module, ValType::I32)) {
2633
75.9k
        return false;
2634
5.26k
    }
2635
5.26k
    let t = builder.operands()[builder.operands().len() - 2];
2636
5.26k
    let u = builder.operands()[builder.operands().len() - 3];
2637
5.26k
    t.is_none() || u.is_none() || t == u
2638
81.2k
}
2639
2640
116
fn select(
2641
116
    _: &mut Unstructured,
2642
116
    _module: &Module,
2643
116
    builder: &mut CodeBuilder,
2644
116
    instructions: &mut Vec<Instruction>,
2645
116
) -> Result<()> {
2646
116
    builder.pop_operand();
2647
116
    let t = builder.pop_operand();
2648
116
    let u = builder.pop_operand();
2649
116
    let ty = t.or(u);
2650
116
    builder.allocs.operands.push(ty);
2651
116
    match ty {
2652
0
        Some(ty @ ValType::Ref(_)) => instructions.push(Instruction::TypedSelect(ty)),
2653
        Some(ValType::I32) | Some(ValType::I64) | Some(ValType::F32) | Some(ValType::F64)
2654
78
        | Some(ValType::V128) | None => instructions.push(Instruction::Select),
2655
    }
2656
78
    Ok(())
2657
78
}
2658
2659
#[inline]
2660
81.2k
fn local_get_valid(_module: &Module, builder: &mut CodeBuilder) -> bool {
2661
81.2k
    !builder.func_ty.params.is_empty() || !builder.locals.is_empty()
2662
81.2k
}
2663
2664
2.89k
fn local_get(
2665
2.89k
    u: &mut Unstructured,
2666
2.89k
    _module: &Module,
2667
2.89k
    builder: &mut CodeBuilder,
2668
2.89k
    instructions: &mut Vec<Instruction>,
2669
2.89k
) -> Result<()> {
2670
2.89k
    let num_params = builder.func_ty.params.len();
2671
2.89k
    let n = num_params + builder.locals.len();
2672
2.89k
    debug_assert!(n > 0);
2673
2.89k
    let i = u.int_in_range(0..=n - 1)?;
2674
2.89k
    builder.allocs.operands.push(Some(if i < num_params {
2675
673
        builder.func_ty.params[i]
2676
    } else {
2677
2.22k
        builder.locals[i - num_params]
2678
    }));
2679
2.89k
    instructions.push(Instruction::LocalGet(i as u32));
2680
2.89k
    Ok(())
2681
2.89k
}
2682
2683
#[inline]
2684
162k
fn local_set_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2685
162k
    builder
2686
162k
        .func_ty
2687
162k
        .params
2688
162k
        .iter()
2689
162k
        .chain(builder.locals.iter())
2690
162k
        .any(|ty| builder.type_on_stack(module, *ty))
2691
162k
}
2692
2693
623
fn local_set(
2694
623
    u: &mut Unstructured,
2695
623
    module: &Module,
2696
623
    builder: &mut CodeBuilder,
2697
623
    instructions: &mut Vec<Instruction>,
2698
623
) -> Result<()> {
2699
623
    let n = builder
2700
623
        .func_ty
2701
623
        .params
2702
623
        .iter()
2703
623
        .chain(builder.locals.iter())
2704
3.04k
        .filter(|ty| builder.type_on_stack(module, **ty))
2705
623
        .count();
2706
623
    debug_assert!(n > 0);
2707
623
    let i = u.int_in_range(0..=n - 1)?;
2708
623
    let (j, _) = builder
2709
623
        .func_ty
2710
623
        .params
2711
623
        .iter()
2712
623
        .chain(builder.locals.iter())
2713
623
        .enumerate()
2714
2.37k
        .filter(|(_, ty)| builder.type_on_stack(module, **ty))
2715
623
        .nth(i)
2716
623
        .unwrap();
2717
623
    builder.allocs.operands.pop();
2718
623
    instructions.push(Instruction::LocalSet(j as u32));
2719
623
    Ok(())
2720
623
}
2721
2722
1.00k
fn local_tee(
2723
1.00k
    u: &mut Unstructured,
2724
1.00k
    module: &Module,
2725
1.00k
    builder: &mut CodeBuilder,
2726
1.00k
    instructions: &mut Vec<Instruction>,
2727
1.00k
) -> Result<()> {
2728
1.00k
    let n = builder
2729
1.00k
        .func_ty
2730
1.00k
        .params
2731
1.00k
        .iter()
2732
1.00k
        .chain(builder.locals.iter())
2733
6.49k
        .filter(|ty| builder.type_on_stack(module, **ty))
2734
1.00k
        .count();
2735
1.00k
    debug_assert!(n > 0);
2736
1.00k
    let i = u.int_in_range(0..=n - 1)?;
2737
1.00k
    let (j, ty) = builder
2738
1.00k
        .func_ty
2739
1.00k
        .params
2740
1.00k
        .iter()
2741
1.00k
        .chain(builder.locals.iter())
2742
1.00k
        .enumerate()
2743
3.99k
        .filter(|(_, ty)| builder.type_on_stack(module, **ty))
2744
1.00k
        .nth(i)
2745
1.00k
        .unwrap();
2746
1.00k
    builder.allocs.operands.pop();
2747
1.00k
    instructions.push(Instruction::LocalTee(j as u32));
2748
1.00k
    builder.push_operand(Some(*ty));
2749
1.00k
    Ok(())
2750
1.00k
}
2751
2752
#[inline]
2753
81.2k
fn global_get_valid(module: &Module, _: &mut CodeBuilder) -> bool {
2754
81.2k
    module.globals.len() > 0
2755
81.2k
}
2756
2757
1.68k
fn global_get(
2758
1.68k
    u: &mut Unstructured,
2759
1.68k
    module: &Module,
2760
1.68k
    builder: &mut CodeBuilder,
2761
1.68k
    instructions: &mut Vec<Instruction>,
2762
1.68k
) -> Result<()> {
2763
1.68k
    debug_assert!(module.globals.len() > 0);
2764
1.68k
    let global_idx = u.int_in_range(0..=module.globals.len() - 1)?;
2765
1.68k
    builder
2766
1.68k
        .allocs
2767
1.68k
        .operands
2768
1.68k
        .push(Some(module.globals[global_idx].val_type));
2769
1.68k
    instructions.push(Instruction::GlobalGet(global_idx as u32));
2770
1.68k
    Ok(())
2771
1.68k
}
2772
2773
#[inline]
2774
81.2k
fn global_set_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
2775
81.2k
    builder
2776
81.2k
        .allocs
2777
81.2k
        .mutable_globals
2778
81.2k
        .iter()
2779
81.2k
        .any(|(ty, _)| builder.type_on_stack(module, *ty))
2780
81.2k
}
2781
2782
207
fn global_set(
2783
207
    u: &mut Unstructured,
2784
207
    module: &Module,
2785
207
    builder: &mut CodeBuilder,
2786
207
    instructions: &mut Vec<Instruction>,
2787
207
) -> Result<()> {
2788
207
    let candidates = builder
2789
207
        .allocs
2790
207
        .mutable_globals
2791
207
        .iter()
2792
272
        .find(|(ty, _)| builder.type_on_stack(module, **ty))
2793
207
        .unwrap()
2794
207
        .1;
2795
207
    let i = u.int_in_range(0..=candidates.len() - 1)?;
2796
207
    builder.allocs.operands.pop();
2797
207
    instructions.push(Instruction::GlobalSet(candidates[i]));
2798
207
    Ok(())
2799
207
}
2800
2801
#[inline]
2802
81.2k
fn have_memory(module: &Module, _: &mut CodeBuilder) -> bool {
2803
81.2k
    module.memories.len() > 0
2804
81.2k
}
2805
2806
#[inline]
2807
1.13M
fn have_memory_and_offset(module: &Module, builder: &mut CodeBuilder) -> bool {
2808
1.13M
    (builder.allocs.memory32.len() > 0 && builder.type_on_stack(module, ValType::I32))
2809
1.00M
        || (builder.allocs.memory64.len() > 0 && builder.type_on_stack(module, ValType::I64))
2810
1.13M
}
2811
2812
#[inline]
2813
81.2k
fn have_data(module: &Module, _: &mut CodeBuilder) -> bool {
2814
81.2k
    module.data.len() > 0
2815
81.2k
}
2816
2817
261
fn i32_load(
2818
261
    u: &mut Unstructured,
2819
261
    module: &Module,
2820
261
    builder: &mut CodeBuilder,
2821
261
    instructions: &mut Vec<Instruction>,
2822
261
) -> Result<()> {
2823
261
    let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
2824
261
    builder.allocs.operands.push(Some(ValType::I32));
2825
261
    if module.config.disallow_traps {
2826
0
        no_traps::load(Instruction::I32Load(memarg), module, builder, instructions);
2827
261
    } else {
2828
261
        instructions.push(Instruction::I32Load(memarg));
2829
261
    }
2830
261
    Ok(())
2831
261
}
2832
2833
263
fn i64_load(
2834
263
    u: &mut Unstructured,
2835
263
    module: &Module,
2836
263
    builder: &mut CodeBuilder,
2837
263
    instructions: &mut Vec<Instruction>,
2838
263
) -> Result<()> {
2839
263
    let memarg = mem_arg(u, module, builder, &[0, 1, 2, 3])?;
2840
263
    builder.allocs.operands.push(Some(ValType::I64));
2841
263
    if module.config.disallow_traps {
2842
0
        no_traps::load(Instruction::I64Load(memarg), module, builder, instructions);
2843
263
    } else {
2844
263
        instructions.push(Instruction::I64Load(memarg));
2845
263
    }
2846
263
    Ok(())
2847
263
}
2848
2849
172
fn f32_load(
2850
172
    u: &mut Unstructured,
2851
172
    module: &Module,
2852
172
    builder: &mut CodeBuilder,
2853
172
    instructions: &mut Vec<Instruction>,
2854
172
) -> Result<()> {
2855
172
    let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
2856
172
    builder.allocs.operands.push(Some(ValType::F32));
2857
172
    if module.config.disallow_traps {
2858
0
        no_traps::load(Instruction::F32Load(memarg), module, builder, instructions);
2859
172
    } else {
2860
172
        instructions.push(Instruction::F32Load(memarg));
2861
172
    }
2862
172
    Ok(())
2863
172
}
2864
2865
114
fn f64_load(
2866
114
    u: &mut Unstructured,
2867
114
    module: &Module,
2868
114
    builder: &mut CodeBuilder,
2869
114
    instructions: &mut Vec<Instruction>,
2870
114
) -> Result<()> {
2871
114
    let memarg = mem_arg(u, module, builder, &[0, 1, 2, 3])?;
2872
114
    builder.allocs.operands.push(Some(ValType::F64));
2873
114
    if module.config.disallow_traps {
2874
0
        no_traps::load(Instruction::F64Load(memarg), module, builder, instructions);
2875
114
    } else {
2876
114
        instructions.push(Instruction::F64Load(memarg));
2877
114
    }
2878
114
    Ok(())
2879
114
}
2880
2881
364
fn i32_load_8_s(
2882
364
    u: &mut Unstructured,
2883
364
    module: &Module,
2884
364
    builder: &mut CodeBuilder,
2885
364
    instructions: &mut Vec<Instruction>,
2886
364
) -> Result<()> {
2887
364
    let memarg = mem_arg(u, module, builder, &[0])?;
2888
364
    builder.allocs.operands.push(Some(ValType::I32));
2889
364
    if module.config.disallow_traps {
2890
0
        no_traps::load(
2891
0
            Instruction::I32Load8S(memarg),
2892
0
            module,
2893
0
            builder,
2894
0
            instructions,
2895
0
        );
2896
364
    } else {
2897
364
        instructions.push(Instruction::I32Load8S(memarg));
2898
364
    }
2899
364
    Ok(())
2900
364
}
2901
2902
377
fn i32_load_8_u(
2903
377
    u: &mut Unstructured,
2904
377
    module: &Module,
2905
377
    builder: &mut CodeBuilder,
2906
377
    instructions: &mut Vec<Instruction>,
2907
377
) -> Result<()> {
2908
377
    let memarg = mem_arg(u, module, builder, &[0])?;
2909
377
    builder.allocs.operands.push(Some(ValType::I32));
2910
377
    if module.config.disallow_traps {
2911
0
        no_traps::load(
2912
0
            Instruction::I32Load8U(memarg),
2913
0
            module,
2914
0
            builder,
2915
0
            instructions,
2916
0
        );
2917
377
    } else {
2918
377
        instructions.push(Instruction::I32Load8U(memarg));
2919
377
    }
2920
377
    Ok(())
2921
377
}
2922
2923
355
fn i32_load_16_s(
2924
355
    u: &mut Unstructured,
2925
355
    module: &Module,
2926
355
    builder: &mut CodeBuilder,
2927
355
    instructions: &mut Vec<Instruction>,
2928
355
) -> Result<()> {
2929
355
    let memarg = mem_arg(u, module, builder, &[0, 1])?;
2930
355
    builder.allocs.operands.push(Some(ValType::I32));
2931
355
    if module.config.disallow_traps {
2932
0
        no_traps::load(
2933
0
            Instruction::I32Load16S(memarg),
2934
0
            module,
2935
0
            builder,
2936
0
            instructions,
2937
0
        );
2938
355
    } else {
2939
355
        instructions.push(Instruction::I32Load16S(memarg));
2940
355
    }
2941
355
    Ok(())
2942
355
}
2943
2944
387
fn i32_load_16_u(
2945
387
    u: &mut Unstructured,
2946
387
    module: &Module,
2947
387
    builder: &mut CodeBuilder,
2948
387
    instructions: &mut Vec<Instruction>,
2949
387
) -> Result<()> {
2950
387
    let memarg = mem_arg(u, module, builder, &[0, 1])?;
2951
387
    builder.allocs.operands.push(Some(ValType::I32));
2952
387
    if module.config.disallow_traps {
2953
0
        no_traps::load(
2954
0
            Instruction::I32Load16U(memarg),
2955
0
            module,
2956
0
            builder,
2957
0
            instructions,
2958
0
        );
2959
387
    } else {
2960
387
        instructions.push(Instruction::I32Load16U(memarg));
2961
387
    }
2962
387
    Ok(())
2963
387
}
2964
2965
180
fn i64_load_8_s(
2966
180
    u: &mut Unstructured,
2967
180
    module: &Module,
2968
180
    builder: &mut CodeBuilder,
2969
180
    instructions: &mut Vec<Instruction>,
2970
180
) -> Result<()> {
2971
180
    let memarg = mem_arg(u, module, builder, &[0])?;
2972
180
    builder.allocs.operands.push(Some(ValType::I64));
2973
180
    if module.config.disallow_traps {
2974
0
        no_traps::load(
2975
0
            Instruction::I64Load8S(memarg),
2976
0
            module,
2977
0
            builder,
2978
0
            instructions,
2979
0
        );
2980
180
    } else {
2981
180
        instructions.push(Instruction::I64Load8S(memarg));
2982
180
    }
2983
180
    Ok(())
2984
180
}
2985
2986
220
fn i64_load_16_s(
2987
220
    u: &mut Unstructured,
2988
220
    module: &Module,
2989
220
    builder: &mut CodeBuilder,
2990
220
    instructions: &mut Vec<Instruction>,
2991
220
) -> Result<()> {
2992
220
    let memarg = mem_arg(u, module, builder, &[0, 1])?;
2993
220
    builder.allocs.operands.push(Some(ValType::I64));
2994
220
    if module.config.disallow_traps {
2995
0
        no_traps::load(
2996
0
            Instruction::I64Load16S(memarg),
2997
0
            module,
2998
0
            builder,
2999
0
            instructions,
3000
0
        );
3001
220
    } else {
3002
220
        instructions.push(Instruction::I64Load16S(memarg));
3003
220
    }
3004
220
    Ok(())
3005
220
}
3006
3007
142
fn i64_load_32_s(
3008
142
    u: &mut Unstructured,
3009
142
    module: &Module,
3010
142
    builder: &mut CodeBuilder,
3011
142
    instructions: &mut Vec<Instruction>,
3012
142
) -> Result<()> {
3013
142
    let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
3014
142
    builder.allocs.operands.push(Some(ValType::I64));
3015
142
    if module.config.disallow_traps {
3016
0
        no_traps::load(
3017
0
            Instruction::I64Load32S(memarg),
3018
0
            module,
3019
0
            builder,
3020
0
            instructions,
3021
0
        );
3022
142
    } else {
3023
142
        instructions.push(Instruction::I64Load32S(memarg));
3024
142
    }
3025
142
    Ok(())
3026
142
}
3027
3028
263
fn i64_load_8_u(
3029
263
    u: &mut Unstructured,
3030
263
    module: &Module,
3031
263
    builder: &mut CodeBuilder,
3032
263
    instructions: &mut Vec<Instruction>,
3033
263
) -> Result<()> {
3034
263
    let memarg = mem_arg(u, module, builder, &[0])?;
3035
263
    builder.allocs.operands.push(Some(ValType::I64));
3036
263
    if module.config.disallow_traps {
3037
0
        no_traps::load(
3038
0
            Instruction::I64Load8U(memarg),
3039
0
            module,
3040
0
            builder,
3041
0
            instructions,
3042
0
        );
3043
263
    } else {
3044
263
        instructions.push(Instruction::I64Load8U(memarg));
3045
263
    }
3046
263
    Ok(())
3047
263
}
3048
3049
65
fn i64_load_16_u(
3050
65
    u: &mut Unstructured,
3051
65
    module: &Module,
3052
65
    builder: &mut CodeBuilder,
3053
65
    instructions: &mut Vec<Instruction>,
3054
65
) -> Result<()> {
3055
65
    let memarg = mem_arg(u, module, builder, &[0, 1])?;
3056
65
    builder.allocs.operands.push(Some(ValType::I64));
3057
65
    if module.config.disallow_traps {
3058
0
        no_traps::load(
3059
0
            Instruction::I64Load16U(memarg),
3060
0
            module,
3061
0
            builder,
3062
0
            instructions,
3063
0
        );
3064
65
    } else {
3065
65
        instructions.push(Instruction::I64Load16U(memarg));
3066
65
    }
3067
65
    Ok(())
3068
65
}
3069
3070
115
fn i64_load_32_u(
3071
115
    u: &mut Unstructured,
3072
115
    module: &Module,
3073
115
    builder: &mut CodeBuilder,
3074
115
    instructions: &mut Vec<Instruction>,
3075
115
) -> Result<()> {
3076
115
    let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
3077
115
    builder.allocs.operands.push(Some(ValType::I64));
3078
115
    if module.config.disallow_traps {
3079
0
        no_traps::load(
3080
0
            Instruction::I64Load32U(memarg),
3081
0
            module,
3082
0
            builder,
3083
0
            instructions,
3084
0
        );
3085
115
    } else {
3086
115
        instructions.push(Instruction::I64Load32U(memarg));
3087
115
    }
3088
115
    Ok(())
3089
115
}
3090
3091
#[inline]
3092
731k
fn store_valid(module: &Module, builder: &mut CodeBuilder, f: impl Fn() -> ValType) -> bool {
3093
731k
    (builder.allocs.memory32.len() > 0 && builder.types_on_stack(module, &[ValType::I32, f()]))
3094
719k
        || (builder.allocs.memory64.len() > 0
3095
0
            && builder.types_on_stack(module, &[ValType::I64, f()]))
3096
731k
}
_RINvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11store_validNCNvB2_15f32_store_valid0EB6_
Line
Count
Source
3092
81.2k
fn store_valid(module: &Module, builder: &mut CodeBuilder, f: impl Fn() -> ValType) -> bool {
3093
81.2k
    (builder.allocs.memory32.len() > 0 && builder.types_on_stack(module, &[ValType::I32, f()]))
3094
80.6k
        || (builder.allocs.memory64.len() > 0
3095
0
            && builder.types_on_stack(module, &[ValType::I64, f()]))
3096
81.2k
}
_RINvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11store_validNCNvB2_15f64_store_valid0EB6_
Line
Count
Source
3092
81.2k
fn store_valid(module: &Module, builder: &mut CodeBuilder, f: impl Fn() -> ValType) -> bool {
3093
81.2k
    (builder.allocs.memory32.len() > 0 && builder.types_on_stack(module, &[ValType::I32, f()]))
3094
80.6k
        || (builder.allocs.memory64.len() > 0
3095
0
            && builder.types_on_stack(module, &[ValType::I64, f()]))
3096
81.2k
}
_RINvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11store_validNCNvB2_15i32_store_valid0EB6_
Line
Count
Source
3092
243k
fn store_valid(module: &Module, builder: &mut CodeBuilder, f: impl Fn() -> ValType) -> bool {
3093
243k
    (builder.allocs.memory32.len() > 0 && builder.types_on_stack(module, &[ValType::I32, f()]))
3094
237k
        || (builder.allocs.memory64.len() > 0
3095
0
            && builder.types_on_stack(module, &[ValType::I64, f()]))
3096
243k
}
_RINvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11store_validNCNvB2_15i64_store_valid0EB6_
Line
Count
Source
3092
324k
fn store_valid(module: &Module, builder: &mut CodeBuilder, f: impl Fn() -> ValType) -> bool {
3093
324k
    (builder.allocs.memory32.len() > 0 && builder.types_on_stack(module, &[ValType::I32, f()]))
3094
320k
        || (builder.allocs.memory64.len() > 0
3095
0
            && builder.types_on_stack(module, &[ValType::I64, f()]))
3096
324k
}
Unexecuted instantiation: _RINvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11store_validNCNvB2_21simd_v128_store_valid0EB6_
Unexecuted instantiation: _RINvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11store_validNCNvB2_36simd_have_memory_and_offset_and_v1280EB6_
3097
3098
#[inline]
3099
243k
fn i32_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3100
243k
    store_valid(module, builder, || ValType::I32)
3101
243k
}
3102
3103
20
fn i32_store(
3104
20
    u: &mut Unstructured,
3105
20
    module: &Module,
3106
20
    builder: &mut CodeBuilder,
3107
20
    instructions: &mut Vec<Instruction>,
3108
20
) -> Result<()> {
3109
20
    builder.pop_operands(module, &[ValType::I32]);
3110
20
    let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
3111
20
    if module.config.disallow_traps {
3112
0
        no_traps::store(Instruction::I32Store(memarg), module, builder, instructions);
3113
20
    } else {
3114
20
        instructions.push(Instruction::I32Store(memarg));
3115
20
    }
3116
20
    Ok(())
3117
20
}
3118
3119
#[inline]
3120
324k
fn i64_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3121
324k
    store_valid(module, builder, || ValType::I64)
3122
324k
}
3123
3124
110
fn i64_store(
3125
110
    u: &mut Unstructured,
3126
110
    module: &Module,
3127
110
    builder: &mut CodeBuilder,
3128
110
    instructions: &mut Vec<Instruction>,
3129
110
) -> Result<()> {
3130
110
    builder.pop_operands(module, &[ValType::I64]);
3131
110
    let memarg = mem_arg(u, module, builder, &[0, 1, 2, 3])?;
3132
110
    if module.config.disallow_traps {
3133
0
        no_traps::store(Instruction::I64Store(memarg), module, builder, instructions);
3134
110
    } else {
3135
110
        instructions.push(Instruction::I64Store(memarg));
3136
110
    }
3137
110
    Ok(())
3138
110
}
3139
3140
#[inline]
3141
81.2k
fn f32_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3142
81.2k
    store_valid(module, builder, || ValType::F32)
3143
81.2k
}
3144
3145
37
fn f32_store(
3146
37
    u: &mut Unstructured,
3147
37
    module: &Module,
3148
37
    builder: &mut CodeBuilder,
3149
37
    instructions: &mut Vec<Instruction>,
3150
37
) -> Result<()> {
3151
37
    builder.pop_operands(module, &[ValType::F32]);
3152
37
    let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
3153
37
    if module.config.disallow_traps {
3154
0
        no_traps::store(Instruction::F32Store(memarg), module, builder, instructions);
3155
37
    } else {
3156
37
        instructions.push(Instruction::F32Store(memarg));
3157
37
    }
3158
37
    Ok(())
3159
37
}
3160
3161
#[inline]
3162
81.2k
fn f64_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3163
81.2k
    store_valid(module, builder, || ValType::F64)
3164
81.2k
}
3165
3166
26
fn f64_store(
3167
26
    u: &mut Unstructured,
3168
26
    module: &Module,
3169
26
    builder: &mut CodeBuilder,
3170
26
    instructions: &mut Vec<Instruction>,
3171
26
) -> Result<()> {
3172
26
    builder.pop_operands(module, &[ValType::F64]);
3173
26
    let memarg = mem_arg(u, module, builder, &[0, 1, 2, 3])?;
3174
26
    if module.config.disallow_traps {
3175
0
        no_traps::store(Instruction::F64Store(memarg), module, builder, instructions);
3176
26
    } else {
3177
26
        instructions.push(Instruction::F64Store(memarg));
3178
26
    }
3179
26
    Ok(())
3180
26
}
3181
3182
44
fn i32_store_8(
3183
44
    u: &mut Unstructured,
3184
44
    module: &Module,
3185
44
    builder: &mut CodeBuilder,
3186
44
    instructions: &mut Vec<Instruction>,
3187
44
) -> Result<()> {
3188
44
    builder.pop_operands(module, &[ValType::I32]);
3189
44
    let memarg = mem_arg(u, module, builder, &[0])?;
3190
44
    if module.config.disallow_traps {
3191
0
        no_traps::store(
3192
0
            Instruction::I32Store8(memarg),
3193
0
            module,
3194
0
            builder,
3195
0
            instructions,
3196
0
        );
3197
44
    } else {
3198
44
        instructions.push(Instruction::I32Store8(memarg));
3199
44
    }
3200
44
    Ok(())
3201
44
}
3202
3203
16
fn i32_store_16(
3204
16
    u: &mut Unstructured,
3205
16
    module: &Module,
3206
16
    builder: &mut CodeBuilder,
3207
16
    instructions: &mut Vec<Instruction>,
3208
16
) -> Result<()> {
3209
16
    builder.pop_operands(module, &[ValType::I32]);
3210
16
    let memarg = mem_arg(u, module, builder, &[0, 1])?;
3211
16
    if module.config.disallow_traps {
3212
0
        no_traps::store(
3213
0
            Instruction::I32Store16(memarg),
3214
0
            module,
3215
0
            builder,
3216
0
            instructions,
3217
0
        );
3218
16
    } else {
3219
16
        instructions.push(Instruction::I32Store16(memarg));
3220
16
    }
3221
16
    Ok(())
3222
16
}
3223
3224
65
fn i64_store_8(
3225
65
    u: &mut Unstructured,
3226
65
    module: &Module,
3227
65
    builder: &mut CodeBuilder,
3228
65
    instructions: &mut Vec<Instruction>,
3229
65
) -> Result<()> {
3230
65
    builder.pop_operands(module, &[ValType::I64]);
3231
65
    let memarg = mem_arg(u, module, builder, &[0])?;
3232
65
    if module.config.disallow_traps {
3233
0
        no_traps::store(
3234
0
            Instruction::I64Store8(memarg),
3235
0
            module,
3236
0
            builder,
3237
0
            instructions,
3238
0
        );
3239
65
    } else {
3240
65
        instructions.push(Instruction::I64Store8(memarg));
3241
65
    }
3242
65
    Ok(())
3243
65
}
3244
3245
27
fn i64_store_16(
3246
27
    u: &mut Unstructured,
3247
27
    module: &Module,
3248
27
    builder: &mut CodeBuilder,
3249
27
    instructions: &mut Vec<Instruction>,
3250
27
) -> Result<()> {
3251
27
    builder.pop_operands(module, &[ValType::I64]);
3252
27
    let memarg = mem_arg(u, module, builder, &[0, 1])?;
3253
27
    if module.config.disallow_traps {
3254
0
        no_traps::store(
3255
0
            Instruction::I64Store16(memarg),
3256
0
            module,
3257
0
            builder,
3258
0
            instructions,
3259
0
        );
3260
27
    } else {
3261
27
        instructions.push(Instruction::I64Store16(memarg));
3262
27
    }
3263
27
    Ok(())
3264
27
}
3265
3266
45
fn i64_store_32(
3267
45
    u: &mut Unstructured,
3268
45
    module: &Module,
3269
45
    builder: &mut CodeBuilder,
3270
45
    instructions: &mut Vec<Instruction>,
3271
45
) -> Result<()> {
3272
45
    builder.pop_operands(module, &[ValType::I64]);
3273
45
    let memarg = mem_arg(u, module, builder, &[0, 1, 2])?;
3274
45
    if module.config.disallow_traps {
3275
0
        no_traps::store(
3276
0
            Instruction::I64Store32(memarg),
3277
0
            module,
3278
0
            builder,
3279
0
            instructions,
3280
0
        );
3281
45
    } else {
3282
45
        instructions.push(Instruction::I64Store32(memarg));
3283
45
    }
3284
45
    Ok(())
3285
45
}
3286
3287
1.50k
fn memory_size(
3288
1.50k
    u: &mut Unstructured,
3289
1.50k
    module: &Module,
3290
1.50k
    builder: &mut CodeBuilder,
3291
1.50k
    instructions: &mut Vec<Instruction>,
3292
1.50k
) -> Result<()> {
3293
1.50k
    let i = u.int_in_range(0..=module.memories.len() - 1)?;
3294
1.50k
    let ty = if module.memories[i].memory64 {
3295
0
        ValType::I64
3296
    } else {
3297
1.50k
        ValType::I32
3298
    };
3299
1.50k
    builder.push_operands(&[ty]);
3300
1.50k
    instructions.push(Instruction::MemorySize(i as u32));
3301
1.50k
    Ok(())
3302
1.50k
}
3303
3304
#[inline]
3305
81.2k
fn memory_grow_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3306
81.2k
    (builder.allocs.memory32.len() > 0 && builder.type_on_stack(module, ValType::I32))
3307
71.6k
        || (builder.allocs.memory64.len() > 0 && builder.type_on_stack(module, ValType::I64))
3308
81.2k
}
3309
3310
574
fn memory_grow(
3311
574
    u: &mut Unstructured,
3312
574
    module: &Module,
3313
574
    builder: &mut CodeBuilder,
3314
574
    instructions: &mut Vec<Instruction>,
3315
574
) -> Result<()> {
3316
574
    let ty = if builder.type_on_stack(module, ValType::I32) {
3317
574
        ValType::I32
3318
    } else {
3319
0
        ValType::I64
3320
    };
3321
574
    let index = memory_index(u, builder, ty)?;
3322
574
    builder.pop_operands(module, &[ty]);
3323
574
    builder.push_operands(&[ty]);
3324
574
    instructions.push(Instruction::MemoryGrow(index));
3325
574
    Ok(())
3326
574
}
3327
3328
#[inline]
3329
81.2k
fn memory_init_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3330
81.2k
    module.config.bulk_memory_enabled
3331
0
        && have_data(module, builder)
3332
0
        && !module.config.disallow_traps // Non-trapping memory init not yet implemented
3333
0
        && (builder.allocs.memory32.len() > 0
3334
0
            && builder.types_on_stack(module, &[ValType::I32, ValType::I32, ValType::I32])
3335
0
            || (builder.allocs.memory64.len() > 0
3336
0
                && builder.types_on_stack(module, &[ValType::I64, ValType::I32, ValType::I32])))
3337
81.2k
}
3338
3339
0
fn memory_init(
3340
0
    u: &mut Unstructured,
3341
0
    module: &Module,
3342
0
    builder: &mut CodeBuilder,
3343
0
    instructions: &mut Vec<Instruction>,
3344
0
) -> Result<()> {
3345
0
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3346
0
    let ty = if builder.type_on_stack(module, ValType::I32) {
3347
0
        ValType::I32
3348
    } else {
3349
0
        ValType::I64
3350
    };
3351
0
    let mem = memory_index(u, builder, ty)?;
3352
0
    let data_index = data_index(u, module)?;
3353
0
    builder.pop_operands(module, &[ty]);
3354
0
    instructions.push(Instruction::MemoryInit { mem, data_index });
3355
0
    Ok(())
3356
0
}
3357
3358
#[inline]
3359
81.2k
fn memory_fill_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3360
81.2k
    module.config.bulk_memory_enabled
3361
0
        && !module.config.disallow_traps // Non-trapping memory fill generation not yet implemented
3362
0
        && (builder.allocs.memory32.len() > 0
3363
0
            && builder.types_on_stack(module, &[ValType::I32, ValType::I32, ValType::I32])
3364
0
            || (builder.allocs.memory64.len() > 0
3365
0
                && builder.types_on_stack(module, &[ValType::I64, ValType::I32, ValType::I64])))
3366
81.2k
}
3367
3368
0
fn memory_fill(
3369
0
    u: &mut Unstructured,
3370
0
    module: &Module,
3371
0
    builder: &mut CodeBuilder,
3372
0
    instructions: &mut Vec<Instruction>,
3373
0
) -> Result<()> {
3374
0
    let ty = if builder.type_on_stack(module, ValType::I32) {
3375
0
        ValType::I32
3376
    } else {
3377
0
        ValType::I64
3378
    };
3379
0
    let mem = memory_index(u, builder, ty)?;
3380
0
    builder.pop_operands(module, &[ty, ValType::I32, ty]);
3381
0
    instructions.push(Instruction::MemoryFill(mem));
3382
0
    Ok(())
3383
0
}
3384
3385
#[inline]
3386
81.2k
fn memory_copy_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3387
81.2k
    if !module.config.bulk_memory_enabled {
3388
81.2k
        return false;
3389
0
    }
3390
0
3391
0
    // The non-trapping case for memory copy has not yet been implemented,
3392
0
    // so we are excluding them for now
3393
0
    if module.config.disallow_traps {
3394
0
        return false;
3395
0
    }
3396
0
3397
0
    let n32 = builder.allocs.memory32.len();
3398
0
    let n64 = builder.allocs.memory64.len();
3399
0
3400
0
    if builder.types_on_stack(module, &[ValType::I64, ValType::I64, ValType::I64]) && n64 > 0 {
3401
0
        return true;
3402
0
    }
3403
0
    if builder.types_on_stack(module, &[ValType::I32, ValType::I32, ValType::I32]) && n32 > 0 {
3404
0
        return true;
3405
0
    }
3406
0
    if builder.types_on_stack(module, &[ValType::I64, ValType::I32, ValType::I32])
3407
0
        && n32 > 0
3408
0
        && n64 > 0
3409
    {
3410
0
        return true;
3411
0
    }
3412
0
    if builder.types_on_stack(module, &[ValType::I32, ValType::I64, ValType::I32])
3413
0
        && n32 > 0
3414
0
        && n64 > 0
3415
    {
3416
0
        return true;
3417
0
    }
3418
0
3419
0
    false
3420
81.2k
}
3421
3422
0
fn memory_copy(
3423
0
    u: &mut Unstructured,
3424
0
    module: &Module,
3425
0
    builder: &mut CodeBuilder,
3426
0
    instructions: &mut Vec<Instruction>,
3427
0
) -> Result<()> {
3428
0
    let (src, dst) = gen_copy_src_and_dst(module, builder);
3429
0
    let src_mem = src.choose(u, &builder.allocs.memory32, &builder.allocs.memory64)?;
3430
0
    let dst_mem = dst.choose(u, &builder.allocs.memory32, &builder.allocs.memory64)?;
3431
0
    instructions.push(Instruction::MemoryCopy { dst_mem, src_mem });
3432
0
    Ok(())
3433
0
}
3434
3435
enum CopyIndexSize {
3436
    I32,
3437
    I64,
3438
}
3439
3440
impl CopyIndexSize {
3441
0
    fn choose(&self, u: &mut Unstructured<'_>, n32: &[u32], n64: &[u32]) -> Result<u32> {
3442
0
        Ok(match self {
3443
0
            CopyIndexSize::I32 => *u.choose(n32)?,
3444
0
            CopyIndexSize::I64 => *u.choose(n64)?,
3445
        })
3446
0
    }
3447
}
3448
3449
0
fn gen_copy_src_and_dst(
3450
0
    module: &Module,
3451
0
    builder: &mut CodeBuilder,
3452
0
) -> (CopyIndexSize, CopyIndexSize) {
3453
0
    if builder.types_on_stack(module, &[ValType::I64, ValType::I64, ValType::I64]) {
3454
0
        builder.pop_operands(module, &[ValType::I64, ValType::I64, ValType::I64]);
3455
0
        (CopyIndexSize::I64, CopyIndexSize::I64)
3456
0
    } else if builder.types_on_stack(module, &[ValType::I32, ValType::I32, ValType::I32]) {
3457
0
        builder.pop_operands(module, &[ValType::I32, ValType::I32, ValType::I32]);
3458
0
        (CopyIndexSize::I32, CopyIndexSize::I32)
3459
0
    } else if builder.types_on_stack(module, &[ValType::I64, ValType::I32, ValType::I32]) {
3460
0
        builder.pop_operands(module, &[ValType::I64, ValType::I32, ValType::I32]);
3461
0
        (CopyIndexSize::I32, CopyIndexSize::I64)
3462
0
    } else if builder.types_on_stack(module, &[ValType::I32, ValType::I64, ValType::I32]) {
3463
0
        builder.pop_operands(module, &[ValType::I32, ValType::I64, ValType::I32]);
3464
0
        (CopyIndexSize::I64, CopyIndexSize::I32)
3465
    } else {
3466
0
        unreachable!()
3467
    }
3468
0
}
3469
3470
#[inline]
3471
81.2k
fn data_drop_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
3472
81.2k
    have_data(module, builder) && module.config.bulk_memory_enabled
3473
81.2k
}
3474
3475
0
fn data_drop(
3476
0
    u: &mut Unstructured,
3477
0
    module: &Module,
3478
0
    _builder: &mut CodeBuilder,
3479
0
    instructions: &mut Vec<Instruction>,
3480
0
) -> Result<()> {
3481
0
    instructions.push(Instruction::DataDrop(data_index(u, module)?));
3482
0
    Ok(())
3483
0
}
3484
3485
3.75k
fn i32_const(
3486
3.75k
    u: &mut Unstructured,
3487
3.75k
    module: &Module,
3488
3.75k
    builder: &mut CodeBuilder,
3489
3.75k
    instructions: &mut Vec<Instruction>,
3490
3.75k
) -> Result<()> {
3491
3.75k
    builder.push_operands(&[ValType::I32]);
3492
3.75k
    instructions.push(module.arbitrary_const_instruction(ValType::I32, u)?);
3493
3.75k
    Ok(())
3494
3.75k
}
3495
3496
2.46k
fn i64_const(
3497
2.46k
    u: &mut Unstructured,
3498
2.46k
    module: &Module,
3499
2.46k
    builder: &mut CodeBuilder,
3500
2.46k
    instructions: &mut Vec<Instruction>,
3501
2.46k
) -> Result<()> {
3502
2.46k
    builder.push_operands(&[ValType::I64]);
3503
2.46k
    instructions.push(module.arbitrary_const_instruction(ValType::I64, u)?);
3504
2.46k
    Ok(())
3505
2.46k
}
3506
3507
2.44k
fn f32_const(
3508
2.44k
    u: &mut Unstructured,
3509
2.44k
    module: &Module,
3510
2.44k
    builder: &mut CodeBuilder,
3511
2.44k
    instructions: &mut Vec<Instruction>,
3512
2.44k
) -> Result<()> {
3513
2.44k
    builder.push_operands(&[ValType::F32]);
3514
2.44k
    instructions.push(module.arbitrary_const_instruction(ValType::F32, u)?);
3515
2.44k
    Ok(())
3516
2.44k
}
3517
3518
2.12k
fn f64_const(
3519
2.12k
    u: &mut Unstructured,
3520
2.12k
    module: &Module,
3521
2.12k
    builder: &mut CodeBuilder,
3522
2.12k
    instructions: &mut Vec<Instruction>,
3523
2.12k
) -> Result<()> {
3524
2.12k
    builder.push_operands(&[ValType::F64]);
3525
2.12k
    instructions.push(module.arbitrary_const_instruction(ValType::F64, u)?);
3526
2.12k
    Ok(())
3527
2.12k
}
3528
3529
#[inline]
3530
1.05M
fn i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3531
1.05M
    builder.type_on_stack(module, ValType::I32)
3532
1.05M
}
3533
3534
679
fn i32_eqz(
3535
679
    _: &mut Unstructured,
3536
679
    module: &Module,
3537
679
    builder: &mut CodeBuilder,
3538
679
    instructions: &mut Vec<Instruction>,
3539
679
) -> Result<()> {
3540
679
    builder.pop_operands(module, &[ValType::I32]);
3541
679
    builder.push_operands(&[ValType::I32]);
3542
679
    instructions.push(Instruction::I32Eqz);
3543
679
    Ok(())
3544
679
}
3545
3546
#[inline]
3547
2.03M
fn i32_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3548
2.03M
    builder.types_on_stack(module, &[ValType::I32, ValType::I32])
3549
2.03M
}
3550
3551
104
fn i32_eq(
3552
104
    _: &mut Unstructured,
3553
104
    module: &Module,
3554
104
    builder: &mut CodeBuilder,
3555
104
    instructions: &mut Vec<Instruction>,
3556
104
) -> Result<()> {
3557
104
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3558
104
    builder.push_operands(&[ValType::I32]);
3559
104
    instructions.push(Instruction::I32Eq);
3560
104
    Ok(())
3561
104
}
3562
3563
83
fn i32_ne(
3564
83
    _: &mut Unstructured,
3565
83
    module: &Module,
3566
83
    builder: &mut CodeBuilder,
3567
83
    instructions: &mut Vec<Instruction>,
3568
83
) -> Result<()> {
3569
83
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3570
83
    builder.push_operands(&[ValType::I32]);
3571
83
    instructions.push(Instruction::I32Ne);
3572
83
    Ok(())
3573
83
}
3574
3575
86
fn i32_lt_s(
3576
86
    _: &mut Unstructured,
3577
86
    module: &Module,
3578
86
    builder: &mut CodeBuilder,
3579
86
    instructions: &mut Vec<Instruction>,
3580
86
) -> Result<()> {
3581
86
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3582
86
    builder.push_operands(&[ValType::I32]);
3583
86
    instructions.push(Instruction::I32LtS);
3584
86
    Ok(())
3585
86
}
3586
3587
96
fn i32_lt_u(
3588
96
    _: &mut Unstructured,
3589
96
    module: &Module,
3590
96
    builder: &mut CodeBuilder,
3591
96
    instructions: &mut Vec<Instruction>,
3592
96
) -> Result<()> {
3593
96
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3594
96
    builder.push_operands(&[ValType::I32]);
3595
96
    instructions.push(Instruction::I32LtU);
3596
96
    Ok(())
3597
96
}
3598
3599
209
fn i32_gt_s(
3600
209
    _: &mut Unstructured,
3601
209
    module: &Module,
3602
209
    builder: &mut CodeBuilder,
3603
209
    instructions: &mut Vec<Instruction>,
3604
209
) -> Result<()> {
3605
209
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3606
209
    builder.push_operands(&[ValType::I32]);
3607
209
    instructions.push(Instruction::I32GtS);
3608
209
    Ok(())
3609
209
}
3610
3611
35
fn i32_gt_u(
3612
35
    _: &mut Unstructured,
3613
35
    module: &Module,
3614
35
    builder: &mut CodeBuilder,
3615
35
    instructions: &mut Vec<Instruction>,
3616
35
) -> Result<()> {
3617
35
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3618
35
    builder.push_operands(&[ValType::I32]);
3619
35
    instructions.push(Instruction::I32GtU);
3620
35
    Ok(())
3621
35
}
3622
3623
83
fn i32_le_s(
3624
83
    _: &mut Unstructured,
3625
83
    module: &Module,
3626
83
    builder: &mut CodeBuilder,
3627
83
    instructions: &mut Vec<Instruction>,
3628
83
) -> Result<()> {
3629
83
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3630
83
    builder.push_operands(&[ValType::I32]);
3631
83
    instructions.push(Instruction::I32LeS);
3632
83
    Ok(())
3633
83
}
3634
3635
62
fn i32_le_u(
3636
62
    _: &mut Unstructured,
3637
62
    module: &Module,
3638
62
    builder: &mut CodeBuilder,
3639
62
    instructions: &mut Vec<Instruction>,
3640
62
) -> Result<()> {
3641
62
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3642
62
    builder.push_operands(&[ValType::I32]);
3643
62
    instructions.push(Instruction::I32LeU);
3644
62
    Ok(())
3645
62
}
3646
3647
58
fn i32_ge_s(
3648
58
    _: &mut Unstructured,
3649
58
    module: &Module,
3650
58
    builder: &mut CodeBuilder,
3651
58
    instructions: &mut Vec<Instruction>,
3652
58
) -> Result<()> {
3653
58
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3654
58
    builder.push_operands(&[ValType::I32]);
3655
58
    instructions.push(Instruction::I32GeS);
3656
58
    Ok(())
3657
58
}
3658
3659
57
fn i32_ge_u(
3660
57
    _: &mut Unstructured,
3661
57
    module: &Module,
3662
57
    builder: &mut CodeBuilder,
3663
57
    instructions: &mut Vec<Instruction>,
3664
57
) -> Result<()> {
3665
57
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
3666
57
    builder.push_operands(&[ValType::I32]);
3667
57
    instructions.push(Instruction::I32GeU);
3668
57
    Ok(())
3669
57
}
3670
3671
#[inline]
3672
1.05M
fn i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3673
1.05M
    builder.types_on_stack(module, &[ValType::I64])
3674
1.05M
}
3675
3676
420
fn i64_eqz(
3677
420
    _: &mut Unstructured,
3678
420
    module: &Module,
3679
420
    builder: &mut CodeBuilder,
3680
420
    instructions: &mut Vec<Instruction>,
3681
420
) -> Result<()> {
3682
420
    builder.pop_operands(module, &[ValType::I64]);
3683
420
    builder.push_operands(&[ValType::I32]);
3684
420
    instructions.push(Instruction::I64Eqz);
3685
420
    Ok(())
3686
420
}
3687
3688
#[inline]
3689
2.03M
fn i64_i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3690
2.03M
    builder.types_on_stack(module, &[ValType::I64, ValType::I64])
3691
2.03M
}
3692
3693
25
fn i64_eq(
3694
25
    _: &mut Unstructured,
3695
25
    module: &Module,
3696
25
    builder: &mut CodeBuilder,
3697
25
    instructions: &mut Vec<Instruction>,
3698
25
) -> Result<()> {
3699
25
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3700
25
    builder.push_operands(&[ValType::I32]);
3701
25
    instructions.push(Instruction::I64Eq);
3702
25
    Ok(())
3703
25
}
3704
3705
30
fn i64_ne(
3706
30
    _: &mut Unstructured,
3707
30
    module: &Module,
3708
30
    builder: &mut CodeBuilder,
3709
30
    instructions: &mut Vec<Instruction>,
3710
30
) -> Result<()> {
3711
30
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3712
30
    builder.push_operands(&[ValType::I32]);
3713
30
    instructions.push(Instruction::I64Ne);
3714
30
    Ok(())
3715
30
}
3716
3717
27
fn i64_lt_s(
3718
27
    _: &mut Unstructured,
3719
27
    module: &Module,
3720
27
    builder: &mut CodeBuilder,
3721
27
    instructions: &mut Vec<Instruction>,
3722
27
) -> Result<()> {
3723
27
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3724
27
    builder.push_operands(&[ValType::I32]);
3725
27
    instructions.push(Instruction::I64LtS);
3726
27
    Ok(())
3727
27
}
3728
3729
55
fn i64_lt_u(
3730
55
    _: &mut Unstructured,
3731
55
    module: &Module,
3732
55
    builder: &mut CodeBuilder,
3733
55
    instructions: &mut Vec<Instruction>,
3734
55
) -> Result<()> {
3735
55
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3736
55
    builder.push_operands(&[ValType::I32]);
3737
55
    instructions.push(Instruction::I64LtU);
3738
55
    Ok(())
3739
55
}
3740
3741
23
fn i64_gt_s(
3742
23
    _: &mut Unstructured,
3743
23
    module: &Module,
3744
23
    builder: &mut CodeBuilder,
3745
23
    instructions: &mut Vec<Instruction>,
3746
23
) -> Result<()> {
3747
23
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3748
23
    builder.push_operands(&[ValType::I32]);
3749
23
    instructions.push(Instruction::I64GtS);
3750
23
    Ok(())
3751
23
}
3752
3753
89
fn i64_gt_u(
3754
89
    _: &mut Unstructured,
3755
89
    module: &Module,
3756
89
    builder: &mut CodeBuilder,
3757
89
    instructions: &mut Vec<Instruction>,
3758
89
) -> Result<()> {
3759
89
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3760
89
    builder.push_operands(&[ValType::I32]);
3761
89
    instructions.push(Instruction::I64GtU);
3762
89
    Ok(())
3763
89
}
3764
3765
53
fn i64_le_s(
3766
53
    _: &mut Unstructured,
3767
53
    module: &Module,
3768
53
    builder: &mut CodeBuilder,
3769
53
    instructions: &mut Vec<Instruction>,
3770
53
) -> Result<()> {
3771
53
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3772
53
    builder.push_operands(&[ValType::I32]);
3773
53
    instructions.push(Instruction::I64LeS);
3774
53
    Ok(())
3775
53
}
3776
3777
53
fn i64_le_u(
3778
53
    _: &mut Unstructured,
3779
53
    module: &Module,
3780
53
    builder: &mut CodeBuilder,
3781
53
    instructions: &mut Vec<Instruction>,
3782
53
) -> Result<()> {
3783
53
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3784
53
    builder.push_operands(&[ValType::I32]);
3785
53
    instructions.push(Instruction::I64LeU);
3786
53
    Ok(())
3787
53
}
3788
3789
49
fn i64_ge_s(
3790
49
    _: &mut Unstructured,
3791
49
    module: &Module,
3792
49
    builder: &mut CodeBuilder,
3793
49
    instructions: &mut Vec<Instruction>,
3794
49
) -> Result<()> {
3795
49
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3796
49
    builder.push_operands(&[ValType::I32]);
3797
49
    instructions.push(Instruction::I64GeS);
3798
49
    Ok(())
3799
49
}
3800
3801
84
fn i64_ge_u(
3802
84
    _: &mut Unstructured,
3803
84
    module: &Module,
3804
84
    builder: &mut CodeBuilder,
3805
84
    instructions: &mut Vec<Instruction>,
3806
84
) -> Result<()> {
3807
84
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
3808
84
    builder.push_operands(&[ValType::I32]);
3809
84
    instructions.push(Instruction::I64GeU);
3810
84
    Ok(())
3811
84
}
3812
3813
1.05M
fn f32_f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3814
1.05M
    builder.types_on_stack(module, &[ValType::F32, ValType::F32])
3815
1.05M
}
3816
3817
22
fn f32_eq(
3818
22
    _: &mut Unstructured,
3819
22
    module: &Module,
3820
22
    builder: &mut CodeBuilder,
3821
22
    instructions: &mut Vec<Instruction>,
3822
22
) -> Result<()> {
3823
22
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
3824
22
    builder.push_operands(&[ValType::I32]);
3825
22
    instructions.push(Instruction::F32Eq);
3826
22
    Ok(())
3827
22
}
3828
3829
27
fn f32_ne(
3830
27
    _: &mut Unstructured,
3831
27
    module: &Module,
3832
27
    builder: &mut CodeBuilder,
3833
27
    instructions: &mut Vec<Instruction>,
3834
27
) -> Result<()> {
3835
27
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
3836
27
    builder.push_operands(&[ValType::I32]);
3837
27
    instructions.push(Instruction::F32Ne);
3838
27
    Ok(())
3839
27
}
3840
3841
20
fn f32_lt(
3842
20
    _: &mut Unstructured,
3843
20
    module: &Module,
3844
20
    builder: &mut CodeBuilder,
3845
20
    instructions: &mut Vec<Instruction>,
3846
20
) -> Result<()> {
3847
20
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
3848
20
    builder.push_operands(&[ValType::I32]);
3849
20
    instructions.push(Instruction::F32Lt);
3850
20
    Ok(())
3851
20
}
3852
3853
17
fn f32_gt(
3854
17
    _: &mut Unstructured,
3855
17
    module: &Module,
3856
17
    builder: &mut CodeBuilder,
3857
17
    instructions: &mut Vec<Instruction>,
3858
17
) -> Result<()> {
3859
17
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
3860
17
    builder.push_operands(&[ValType::I32]);
3861
17
    instructions.push(Instruction::F32Gt);
3862
17
    Ok(())
3863
17
}
3864
3865
30
fn f32_le(
3866
30
    _: &mut Unstructured,
3867
30
    module: &Module,
3868
30
    builder: &mut CodeBuilder,
3869
30
    instructions: &mut Vec<Instruction>,
3870
30
) -> Result<()> {
3871
30
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
3872
30
    builder.push_operands(&[ValType::I32]);
3873
30
    instructions.push(Instruction::F32Le);
3874
30
    Ok(())
3875
30
}
3876
3877
34
fn f32_ge(
3878
34
    _: &mut Unstructured,
3879
34
    module: &Module,
3880
34
    builder: &mut CodeBuilder,
3881
34
    instructions: &mut Vec<Instruction>,
3882
34
) -> Result<()> {
3883
34
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
3884
34
    builder.push_operands(&[ValType::I32]);
3885
34
    instructions.push(Instruction::F32Ge);
3886
34
    Ok(())
3887
34
}
3888
3889
1.05M
fn f64_f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
3890
1.05M
    builder.types_on_stack(module, &[ValType::F64, ValType::F64])
3891
1.05M
}
3892
3893
30
fn f64_eq(
3894
30
    _: &mut Unstructured,
3895
30
    module: &Module,
3896
30
    builder: &mut CodeBuilder,
3897
30
    instructions: &mut Vec<Instruction>,
3898
30
) -> Result<()> {
3899
30
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
3900
30
    builder.push_operands(&[ValType::I32]);
3901
30
    instructions.push(Instruction::F64Eq);
3902
30
    Ok(())
3903
30
}
3904
3905
18
fn f64_ne(
3906
18
    _: &mut Unstructured,
3907
18
    module: &Module,
3908
18
    builder: &mut CodeBuilder,
3909
18
    instructions: &mut Vec<Instruction>,
3910
18
) -> Result<()> {
3911
18
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
3912
18
    builder.push_operands(&[ValType::I32]);
3913
18
    instructions.push(Instruction::F64Ne);
3914
18
    Ok(())
3915
18
}
3916
3917
8
fn f64_lt(
3918
8
    _: &mut Unstructured,
3919
8
    module: &Module,
3920
8
    builder: &mut CodeBuilder,
3921
8
    instructions: &mut Vec<Instruction>,
3922
8
) -> Result<()> {
3923
8
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
3924
8
    builder.push_operands(&[ValType::I32]);
3925
8
    instructions.push(Instruction::F64Lt);
3926
8
    Ok(())
3927
8
}
3928
3929
25
fn f64_gt(
3930
25
    _: &mut Unstructured,
3931
25
    module: &Module,
3932
25
    builder: &mut CodeBuilder,
3933
25
    instructions: &mut Vec<Instruction>,
3934
25
) -> Result<()> {
3935
25
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
3936
25
    builder.push_operands(&[ValType::I32]);
3937
25
    instructions.push(Instruction::F64Gt);
3938
25
    Ok(())
3939
25
}
3940
3941
7
fn f64_le(
3942
7
    _: &mut Unstructured,
3943
7
    module: &Module,
3944
7
    builder: &mut CodeBuilder,
3945
7
    instructions: &mut Vec<Instruction>,
3946
7
) -> Result<()> {
3947
7
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
3948
7
    builder.push_operands(&[ValType::I32]);
3949
7
    instructions.push(Instruction::F64Le);
3950
7
    Ok(())
3951
7
}
3952
3953
19
fn f64_ge(
3954
19
    _: &mut Unstructured,
3955
19
    module: &Module,
3956
19
    builder: &mut CodeBuilder,
3957
19
    instructions: &mut Vec<Instruction>,
3958
19
) -> Result<()> {
3959
19
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
3960
19
    builder.push_operands(&[ValType::I32]);
3961
19
    instructions.push(Instruction::F64Ge);
3962
19
    Ok(())
3963
19
}
3964
3965
745
fn i32_clz(
3966
745
    _: &mut Unstructured,
3967
745
    module: &Module,
3968
745
    builder: &mut CodeBuilder,
3969
745
    instructions: &mut Vec<Instruction>,
3970
745
) -> Result<()> {
3971
745
    builder.pop_operands(module, &[ValType::I32]);
3972
745
    builder.push_operands(&[ValType::I32]);
3973
745
    instructions.push(Instruction::I32Clz);
3974
745
    Ok(())
3975
745
}
3976
3977
686
fn i32_ctz(
3978
686
    _: &mut Unstructured,
3979
686
    module: &Module,
3980
686
    builder: &mut CodeBuilder,
3981
686
    instructions: &mut Vec<Instruction>,
3982
686
) -> Result<()> {
3983
686
    builder.pop_operands(module, &[ValType::I32]);
3984
686
    builder.push_operands(&[ValType::I32]);
3985
686
    instructions.push(Instruction::I32Ctz);
3986
686
    Ok(())
3987
686
}
3988
3989
570
fn i32_popcnt(
3990
570
    _: &mut Unstructured,
3991
570
    module: &Module,
3992
570
    builder: &mut CodeBuilder,
3993
570
    instructions: &mut Vec<Instruction>,
3994
570
) -> Result<()> {
3995
570
    builder.pop_operands(module, &[ValType::I32]);
3996
570
    builder.push_operands(&[ValType::I32]);
3997
570
    instructions.push(Instruction::I32Popcnt);
3998
570
    Ok(())
3999
570
}
4000
4001
50
fn i32_add(
4002
50
    _: &mut Unstructured,
4003
50
    module: &Module,
4004
50
    builder: &mut CodeBuilder,
4005
50
    instructions: &mut Vec<Instruction>,
4006
50
) -> Result<()> {
4007
50
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4008
50
    builder.push_operands(&[ValType::I32]);
4009
50
    instructions.push(Instruction::I32Add);
4010
50
    Ok(())
4011
50
}
4012
4013
132
fn i32_sub(
4014
132
    _: &mut Unstructured,
4015
132
    module: &Module,
4016
132
    builder: &mut CodeBuilder,
4017
132
    instructions: &mut Vec<Instruction>,
4018
132
) -> Result<()> {
4019
132
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4020
132
    builder.push_operands(&[ValType::I32]);
4021
132
    instructions.push(Instruction::I32Sub);
4022
132
    Ok(())
4023
132
}
4024
4025
245
fn i32_mul(
4026
245
    _: &mut Unstructured,
4027
245
    module: &Module,
4028
245
    builder: &mut CodeBuilder,
4029
245
    instructions: &mut Vec<Instruction>,
4030
245
) -> Result<()> {
4031
245
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4032
245
    builder.push_operands(&[ValType::I32]);
4033
245
    instructions.push(Instruction::I32Mul);
4034
245
    Ok(())
4035
245
}
4036
4037
83
fn i32_div_s(
4038
83
    _: &mut Unstructured,
4039
83
    module: &Module,
4040
83
    builder: &mut CodeBuilder,
4041
83
    instructions: &mut Vec<Instruction>,
4042
83
) -> Result<()> {
4043
83
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4044
83
    builder.push_operands(&[ValType::I32]);
4045
83
    if module.config.disallow_traps {
4046
0
        no_traps::signed_div_rem(Instruction::I32DivS, builder, instructions);
4047
83
    } else {
4048
83
        instructions.push(Instruction::I32DivS);
4049
83
    }
4050
83
    Ok(())
4051
83
}
4052
4053
150
fn i32_div_u(
4054
150
    _: &mut Unstructured,
4055
150
    module: &Module,
4056
150
    builder: &mut CodeBuilder,
4057
150
    instructions: &mut Vec<Instruction>,
4058
150
) -> Result<()> {
4059
150
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4060
150
    builder.push_operands(&[ValType::I32]);
4061
150
    if module.config.disallow_traps {
4062
0
        no_traps::unsigned_div_rem(Instruction::I32DivU, builder, instructions);
4063
150
    } else {
4064
150
        instructions.push(Instruction::I32DivU);
4065
150
    }
4066
150
    Ok(())
4067
150
}
4068
4069
67
fn i32_rem_s(
4070
67
    _: &mut Unstructured,
4071
67
    module: &Module,
4072
67
    builder: &mut CodeBuilder,
4073
67
    instructions: &mut Vec<Instruction>,
4074
67
) -> Result<()> {
4075
67
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4076
67
    builder.push_operands(&[ValType::I32]);
4077
67
    if module.config.disallow_traps {
4078
0
        no_traps::signed_div_rem(Instruction::I32RemS, builder, instructions);
4079
67
    } else {
4080
67
        instructions.push(Instruction::I32RemS);
4081
67
    }
4082
67
    Ok(())
4083
67
}
4084
4085
153
fn i32_rem_u(
4086
153
    _: &mut Unstructured,
4087
153
    module: &Module,
4088
153
    builder: &mut CodeBuilder,
4089
153
    instructions: &mut Vec<Instruction>,
4090
153
) -> Result<()> {
4091
153
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4092
153
    builder.push_operands(&[ValType::I32]);
4093
153
    if module.config.disallow_traps {
4094
0
        no_traps::unsigned_div_rem(Instruction::I32RemU, builder, instructions);
4095
153
    } else {
4096
153
        instructions.push(Instruction::I32RemU);
4097
153
    }
4098
153
    Ok(())
4099
153
}
4100
4101
182
fn i32_and(
4102
182
    _: &mut Unstructured,
4103
182
    module: &Module,
4104
182
    builder: &mut CodeBuilder,
4105
182
    instructions: &mut Vec<Instruction>,
4106
182
) -> Result<()> {
4107
182
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4108
182
    builder.push_operands(&[ValType::I32]);
4109
182
    instructions.push(Instruction::I32And);
4110
182
    Ok(())
4111
182
}
4112
4113
427
fn i32_or(
4114
427
    _: &mut Unstructured,
4115
427
    module: &Module,
4116
427
    builder: &mut CodeBuilder,
4117
427
    instructions: &mut Vec<Instruction>,
4118
427
) -> Result<()> {
4119
427
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4120
427
    builder.push_operands(&[ValType::I32]);
4121
427
    instructions.push(Instruction::I32Or);
4122
427
    Ok(())
4123
427
}
4124
4125
74
fn i32_xor(
4126
74
    _: &mut Unstructured,
4127
74
    module: &Module,
4128
74
    builder: &mut CodeBuilder,
4129
74
    instructions: &mut Vec<Instruction>,
4130
74
) -> Result<()> {
4131
74
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4132
74
    builder.push_operands(&[ValType::I32]);
4133
74
    instructions.push(Instruction::I32Xor);
4134
74
    Ok(())
4135
74
}
4136
4137
82
fn i32_shl(
4138
82
    _: &mut Unstructured,
4139
82
    module: &Module,
4140
82
    builder: &mut CodeBuilder,
4141
82
    instructions: &mut Vec<Instruction>,
4142
82
) -> Result<()> {
4143
82
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4144
82
    builder.push_operands(&[ValType::I32]);
4145
82
    instructions.push(Instruction::I32Shl);
4146
82
    Ok(())
4147
82
}
4148
4149
73
fn i32_shr_s(
4150
73
    _: &mut Unstructured,
4151
73
    module: &Module,
4152
73
    builder: &mut CodeBuilder,
4153
73
    instructions: &mut Vec<Instruction>,
4154
73
) -> Result<()> {
4155
73
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4156
73
    builder.push_operands(&[ValType::I32]);
4157
73
    instructions.push(Instruction::I32ShrS);
4158
73
    Ok(())
4159
73
}
4160
4161
78
fn i32_shr_u(
4162
78
    _: &mut Unstructured,
4163
78
    module: &Module,
4164
78
    builder: &mut CodeBuilder,
4165
78
    instructions: &mut Vec<Instruction>,
4166
78
) -> Result<()> {
4167
78
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4168
78
    builder.push_operands(&[ValType::I32]);
4169
78
    instructions.push(Instruction::I32ShrU);
4170
78
    Ok(())
4171
78
}
4172
4173
53
fn i32_rotl(
4174
53
    _: &mut Unstructured,
4175
53
    module: &Module,
4176
53
    builder: &mut CodeBuilder,
4177
53
    instructions: &mut Vec<Instruction>,
4178
53
) -> Result<()> {
4179
53
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4180
53
    builder.push_operands(&[ValType::I32]);
4181
53
    instructions.push(Instruction::I32Rotl);
4182
53
    Ok(())
4183
53
}
4184
4185
162
fn i32_rotr(
4186
162
    _: &mut Unstructured,
4187
162
    module: &Module,
4188
162
    builder: &mut CodeBuilder,
4189
162
    instructions: &mut Vec<Instruction>,
4190
162
) -> Result<()> {
4191
162
    builder.pop_operands(module, &[ValType::I32, ValType::I32]);
4192
162
    builder.push_operands(&[ValType::I32]);
4193
162
    instructions.push(Instruction::I32Rotr);
4194
162
    Ok(())
4195
162
}
4196
4197
556
fn i64_clz(
4198
556
    _: &mut Unstructured,
4199
556
    module: &Module,
4200
556
    builder: &mut CodeBuilder,
4201
556
    instructions: &mut Vec<Instruction>,
4202
556
) -> Result<()> {
4203
556
    builder.pop_operands(module, &[ValType::I64]);
4204
556
    builder.push_operands(&[ValType::I64]);
4205
556
    instructions.push(Instruction::I64Clz);
4206
556
    Ok(())
4207
556
}
4208
4209
443
fn i64_ctz(
4210
443
    _: &mut Unstructured,
4211
443
    module: &Module,
4212
443
    builder: &mut CodeBuilder,
4213
443
    instructions: &mut Vec<Instruction>,
4214
443
) -> Result<()> {
4215
443
    builder.pop_operands(module, &[ValType::I64]);
4216
443
    builder.push_operands(&[ValType::I64]);
4217
443
    instructions.push(Instruction::I64Ctz);
4218
443
    Ok(())
4219
443
}
4220
4221
645
fn i64_popcnt(
4222
645
    _: &mut Unstructured,
4223
645
    module: &Module,
4224
645
    builder: &mut CodeBuilder,
4225
645
    instructions: &mut Vec<Instruction>,
4226
645
) -> Result<()> {
4227
645
    builder.pop_operands(module, &[ValType::I64]);
4228
645
    builder.push_operands(&[ValType::I64]);
4229
645
    instructions.push(Instruction::I64Popcnt);
4230
645
    Ok(())
4231
645
}
4232
4233
25
fn i64_add(
4234
25
    _: &mut Unstructured,
4235
25
    module: &Module,
4236
25
    builder: &mut CodeBuilder,
4237
25
    instructions: &mut Vec<Instruction>,
4238
25
) -> Result<()> {
4239
25
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4240
25
    builder.push_operands(&[ValType::I64]);
4241
25
    instructions.push(Instruction::I64Add);
4242
25
    Ok(())
4243
25
}
4244
4245
65
fn i64_sub(
4246
65
    _: &mut Unstructured,
4247
65
    module: &Module,
4248
65
    builder: &mut CodeBuilder,
4249
65
    instructions: &mut Vec<Instruction>,
4250
65
) -> Result<()> {
4251
65
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4252
65
    builder.push_operands(&[ValType::I64]);
4253
65
    instructions.push(Instruction::I64Sub);
4254
65
    Ok(())
4255
65
}
4256
4257
59
fn i64_mul(
4258
59
    _: &mut Unstructured,
4259
59
    module: &Module,
4260
59
    builder: &mut CodeBuilder,
4261
59
    instructions: &mut Vec<Instruction>,
4262
59
) -> Result<()> {
4263
59
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4264
59
    builder.push_operands(&[ValType::I64]);
4265
59
    instructions.push(Instruction::I64Mul);
4266
59
    Ok(())
4267
59
}
4268
4269
158
fn i64_div_s(
4270
158
    _: &mut Unstructured,
4271
158
    module: &Module,
4272
158
    builder: &mut CodeBuilder,
4273
158
    instructions: &mut Vec<Instruction>,
4274
158
) -> Result<()> {
4275
158
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4276
158
    builder.push_operands(&[ValType::I64]);
4277
158
    if module.config.disallow_traps {
4278
0
        no_traps::signed_div_rem(Instruction::I64DivS, builder, instructions);
4279
158
    } else {
4280
158
        instructions.push(Instruction::I64DivS);
4281
158
    }
4282
158
    Ok(())
4283
158
}
4284
4285
116
fn i64_div_u(
4286
116
    _: &mut Unstructured,
4287
116
    module: &Module,
4288
116
    builder: &mut CodeBuilder,
4289
116
    instructions: &mut Vec<Instruction>,
4290
116
) -> Result<()> {
4291
116
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4292
116
    builder.push_operands(&[ValType::I64]);
4293
116
    if module.config.disallow_traps {
4294
0
        no_traps::unsigned_div_rem(Instruction::I64DivU, builder, instructions);
4295
116
    } else {
4296
116
        instructions.push(Instruction::I64DivU);
4297
116
    }
4298
116
    Ok(())
4299
116
}
4300
4301
54
fn i64_rem_s(
4302
54
    _: &mut Unstructured,
4303
54
    module: &Module,
4304
54
    builder: &mut CodeBuilder,
4305
54
    instructions: &mut Vec<Instruction>,
4306
54
) -> Result<()> {
4307
54
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4308
54
    builder.push_operands(&[ValType::I64]);
4309
54
    if module.config.disallow_traps {
4310
0
        no_traps::signed_div_rem(Instruction::I64RemS, builder, instructions);
4311
54
    } else {
4312
54
        instructions.push(Instruction::I64RemS);
4313
54
    }
4314
54
    Ok(())
4315
54
}
4316
4317
40
fn i64_rem_u(
4318
40
    _: &mut Unstructured,
4319
40
    module: &Module,
4320
40
    builder: &mut CodeBuilder,
4321
40
    instructions: &mut Vec<Instruction>,
4322
40
) -> Result<()> {
4323
40
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4324
40
    builder.push_operands(&[ValType::I64]);
4325
40
    if module.config.disallow_traps {
4326
0
        no_traps::unsigned_div_rem(Instruction::I64RemU, builder, instructions);
4327
40
    } else {
4328
40
        instructions.push(Instruction::I64RemU);
4329
40
    }
4330
40
    Ok(())
4331
40
}
4332
4333
117
fn i64_and(
4334
117
    _: &mut Unstructured,
4335
117
    module: &Module,
4336
117
    builder: &mut CodeBuilder,
4337
117
    instructions: &mut Vec<Instruction>,
4338
117
) -> Result<()> {
4339
117
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4340
117
    builder.push_operands(&[ValType::I64]);
4341
117
    instructions.push(Instruction::I64And);
4342
117
    Ok(())
4343
117
}
4344
4345
43
fn i64_or(
4346
43
    _: &mut Unstructured,
4347
43
    module: &Module,
4348
43
    builder: &mut CodeBuilder,
4349
43
    instructions: &mut Vec<Instruction>,
4350
43
) -> Result<()> {
4351
43
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4352
43
    builder.push_operands(&[ValType::I64]);
4353
43
    instructions.push(Instruction::I64Or);
4354
43
    Ok(())
4355
43
}
4356
4357
57
fn i64_xor(
4358
57
    _: &mut Unstructured,
4359
57
    module: &Module,
4360
57
    builder: &mut CodeBuilder,
4361
57
    instructions: &mut Vec<Instruction>,
4362
57
) -> Result<()> {
4363
57
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4364
57
    builder.push_operands(&[ValType::I64]);
4365
57
    instructions.push(Instruction::I64Xor);
4366
57
    Ok(())
4367
57
}
4368
4369
83
fn i64_shl(
4370
83
    _: &mut Unstructured,
4371
83
    module: &Module,
4372
83
    builder: &mut CodeBuilder,
4373
83
    instructions: &mut Vec<Instruction>,
4374
83
) -> Result<()> {
4375
83
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4376
83
    builder.push_operands(&[ValType::I64]);
4377
83
    instructions.push(Instruction::I64Shl);
4378
83
    Ok(())
4379
83
}
4380
4381
68
fn i64_shr_s(
4382
68
    _: &mut Unstructured,
4383
68
    module: &Module,
4384
68
    builder: &mut CodeBuilder,
4385
68
    instructions: &mut Vec<Instruction>,
4386
68
) -> Result<()> {
4387
68
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4388
68
    builder.push_operands(&[ValType::I64]);
4389
68
    instructions.push(Instruction::I64ShrS);
4390
68
    Ok(())
4391
68
}
4392
4393
30
fn i64_shr_u(
4394
30
    _: &mut Unstructured,
4395
30
    module: &Module,
4396
30
    builder: &mut CodeBuilder,
4397
30
    instructions: &mut Vec<Instruction>,
4398
30
) -> Result<()> {
4399
30
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4400
30
    builder.push_operands(&[ValType::I64]);
4401
30
    instructions.push(Instruction::I64ShrU);
4402
30
    Ok(())
4403
30
}
4404
4405
69
fn i64_rotl(
4406
69
    _: &mut Unstructured,
4407
69
    module: &Module,
4408
69
    builder: &mut CodeBuilder,
4409
69
    instructions: &mut Vec<Instruction>,
4410
69
) -> Result<()> {
4411
69
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4412
69
    builder.push_operands(&[ValType::I64]);
4413
69
    instructions.push(Instruction::I64Rotl);
4414
69
    Ok(())
4415
69
}
4416
4417
35
fn i64_rotr(
4418
35
    _: &mut Unstructured,
4419
35
    module: &Module,
4420
35
    builder: &mut CodeBuilder,
4421
35
    instructions: &mut Vec<Instruction>,
4422
35
) -> Result<()> {
4423
35
    builder.pop_operands(module, &[ValType::I64, ValType::I64]);
4424
35
    builder.push_operands(&[ValType::I64]);
4425
35
    instructions.push(Instruction::I64Rotr);
4426
35
    Ok(())
4427
35
}
4428
4429
#[inline]
4430
1.38M
fn f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
4431
1.38M
    builder.types_on_stack(module, &[ValType::F32])
4432
1.38M
}
4433
4434
1.09k
fn f32_abs(
4435
1.09k
    _: &mut Unstructured,
4436
1.09k
    module: &Module,
4437
1.09k
    builder: &mut CodeBuilder,
4438
1.09k
    instructions: &mut Vec<Instruction>,
4439
1.09k
) -> Result<()> {
4440
1.09k
    builder.pop_operands(module, &[ValType::F32]);
4441
1.09k
    builder.push_operands(&[ValType::F32]);
4442
1.09k
    instructions.push(Instruction::F32Abs);
4443
1.09k
    Ok(())
4444
1.09k
}
4445
4446
714
fn f32_neg(
4447
714
    _: &mut Unstructured,
4448
714
    module: &Module,
4449
714
    builder: &mut CodeBuilder,
4450
714
    instructions: &mut Vec<Instruction>,
4451
714
) -> Result<()> {
4452
714
    builder.pop_operands(module, &[ValType::F32]);
4453
714
    builder.push_operands(&[ValType::F32]);
4454
714
    instructions.push(Instruction::F32Neg);
4455
714
    Ok(())
4456
714
}
4457
4458
471
fn f32_ceil(
4459
471
    _: &mut Unstructured,
4460
471
    module: &Module,
4461
471
    builder: &mut CodeBuilder,
4462
471
    instructions: &mut Vec<Instruction>,
4463
471
) -> Result<()> {
4464
471
    builder.pop_operands(module, &[ValType::F32]);
4465
471
    builder.push_operands(&[ValType::F32]);
4466
471
    instructions.push(Instruction::F32Ceil);
4467
471
    Ok(())
4468
471
}
4469
4470
750
fn f32_floor(
4471
750
    _: &mut Unstructured,
4472
750
    module: &Module,
4473
750
    builder: &mut CodeBuilder,
4474
750
    instructions: &mut Vec<Instruction>,
4475
750
) -> Result<()> {
4476
750
    builder.pop_operands(module, &[ValType::F32]);
4477
750
    builder.push_operands(&[ValType::F32]);
4478
750
    instructions.push(Instruction::F32Floor);
4479
750
    Ok(())
4480
750
}
4481
4482
482
fn f32_trunc(
4483
482
    _: &mut Unstructured,
4484
482
    module: &Module,
4485
482
    builder: &mut CodeBuilder,
4486
482
    instructions: &mut Vec<Instruction>,
4487
482
) -> Result<()> {
4488
482
    builder.pop_operands(module, &[ValType::F32]);
4489
482
    builder.push_operands(&[ValType::F32]);
4490
482
    instructions.push(Instruction::F32Trunc);
4491
482
    Ok(())
4492
482
}
4493
4494
667
fn f32_nearest(
4495
667
    _: &mut Unstructured,
4496
667
    module: &Module,
4497
667
    builder: &mut CodeBuilder,
4498
667
    instructions: &mut Vec<Instruction>,
4499
667
) -> Result<()> {
4500
667
    builder.pop_operands(module, &[ValType::F32]);
4501
667
    builder.push_operands(&[ValType::F32]);
4502
667
    instructions.push(Instruction::F32Nearest);
4503
667
    Ok(())
4504
667
}
4505
4506
1.11k
fn f32_sqrt(
4507
1.11k
    _: &mut Unstructured,
4508
1.11k
    module: &Module,
4509
1.11k
    builder: &mut CodeBuilder,
4510
1.11k
    instructions: &mut Vec<Instruction>,
4511
1.11k
) -> Result<()> {
4512
1.11k
    builder.pop_operands(module, &[ValType::F32]);
4513
1.11k
    builder.push_operands(&[ValType::F32]);
4514
1.11k
    instructions.push(Instruction::F32Sqrt);
4515
1.11k
    Ok(())
4516
1.11k
}
4517
4518
54
fn f32_add(
4519
54
    _: &mut Unstructured,
4520
54
    module: &Module,
4521
54
    builder: &mut CodeBuilder,
4522
54
    instructions: &mut Vec<Instruction>,
4523
54
) -> Result<()> {
4524
54
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
4525
54
    builder.push_operands(&[ValType::F32]);
4526
54
    instructions.push(Instruction::F32Add);
4527
54
    Ok(())
4528
54
}
4529
4530
144
fn f32_sub(
4531
144
    _: &mut Unstructured,
4532
144
    module: &Module,
4533
144
    builder: &mut CodeBuilder,
4534
144
    instructions: &mut Vec<Instruction>,
4535
144
) -> Result<()> {
4536
144
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
4537
144
    builder.push_operands(&[ValType::F32]);
4538
144
    instructions.push(Instruction::F32Sub);
4539
144
    Ok(())
4540
144
}
4541
4542
80
fn f32_mul(
4543
80
    _: &mut Unstructured,
4544
80
    module: &Module,
4545
80
    builder: &mut CodeBuilder,
4546
80
    instructions: &mut Vec<Instruction>,
4547
80
) -> Result<()> {
4548
80
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
4549
80
    builder.push_operands(&[ValType::F32]);
4550
80
    instructions.push(Instruction::F32Mul);
4551
80
    Ok(())
4552
80
}
4553
4554
117
fn f32_div(
4555
117
    _: &mut Unstructured,
4556
117
    module: &Module,
4557
117
    builder: &mut CodeBuilder,
4558
117
    instructions: &mut Vec<Instruction>,
4559
117
) -> Result<()> {
4560
117
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
4561
117
    builder.push_operands(&[ValType::F32]);
4562
117
    instructions.push(Instruction::F32Div);
4563
117
    Ok(())
4564
117
}
4565
4566
45
fn f32_min(
4567
45
    _: &mut Unstructured,
4568
45
    module: &Module,
4569
45
    builder: &mut CodeBuilder,
4570
45
    instructions: &mut Vec<Instruction>,
4571
45
) -> Result<()> {
4572
45
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
4573
45
    builder.push_operands(&[ValType::F32]);
4574
45
    instructions.push(Instruction::F32Min);
4575
45
    Ok(())
4576
45
}
4577
4578
134
fn f32_max(
4579
134
    _: &mut Unstructured,
4580
134
    module: &Module,
4581
134
    builder: &mut CodeBuilder,
4582
134
    instructions: &mut Vec<Instruction>,
4583
134
) -> Result<()> {
4584
134
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
4585
134
    builder.push_operands(&[ValType::F32]);
4586
134
    instructions.push(Instruction::F32Max);
4587
134
    Ok(())
4588
134
}
4589
4590
99
fn f32_copysign(
4591
99
    _: &mut Unstructured,
4592
99
    module: &Module,
4593
99
    builder: &mut CodeBuilder,
4594
99
    instructions: &mut Vec<Instruction>,
4595
99
) -> Result<()> {
4596
99
    builder.pop_operands(module, &[ValType::F32, ValType::F32]);
4597
99
    builder.push_operands(&[ValType::F32]);
4598
99
    instructions.push(Instruction::F32Copysign);
4599
99
    Ok(())
4600
99
}
4601
4602
#[inline]
4603
1.38M
fn f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
4604
1.38M
    builder.types_on_stack(module, &[ValType::F64])
4605
1.38M
}
4606
4607
584
fn f64_abs(
4608
584
    _: &mut Unstructured,
4609
584
    module: &Module,
4610
584
    builder: &mut CodeBuilder,
4611
584
    instructions: &mut Vec<Instruction>,
4612
584
) -> Result<()> {
4613
584
    builder.pop_operands(module, &[ValType::F64]);
4614
584
    builder.push_operands(&[ValType::F64]);
4615
584
    instructions.push(Instruction::F64Abs);
4616
584
    Ok(())
4617
584
}
4618
4619
375
fn f64_neg(
4620
375
    _: &mut Unstructured,
4621
375
    module: &Module,
4622
375
    builder: &mut CodeBuilder,
4623
375
    instructions: &mut Vec<Instruction>,
4624
375
) -> Result<()> {
4625
375
    builder.pop_operands(module, &[ValType::F64]);
4626
375
    builder.push_operands(&[ValType::F64]);
4627
375
    instructions.push(Instruction::F64Neg);
4628
375
    Ok(())
4629
375
}
4630
4631
636
fn f64_ceil(
4632
636
    _: &mut Unstructured,
4633
636
    module: &Module,
4634
636
    builder: &mut CodeBuilder,
4635
636
    instructions: &mut Vec<Instruction>,
4636
636
) -> Result<()> {
4637
636
    builder.pop_operands(module, &[ValType::F64]);
4638
636
    builder.push_operands(&[ValType::F64]);
4639
636
    instructions.push(Instruction::F64Ceil);
4640
636
    Ok(())
4641
636
}
4642
4643
667
fn f64_floor(
4644
667
    _: &mut Unstructured,
4645
667
    module: &Module,
4646
667
    builder: &mut CodeBuilder,
4647
667
    instructions: &mut Vec<Instruction>,
4648
667
) -> Result<()> {
4649
667
    builder.pop_operands(module, &[ValType::F64]);
4650
667
    builder.push_operands(&[ValType::F64]);
4651
667
    instructions.push(Instruction::F64Floor);
4652
667
    Ok(())
4653
667
}
4654
4655
475
fn f64_trunc(
4656
475
    _: &mut Unstructured,
4657
475
    module: &Module,
4658
475
    builder: &mut CodeBuilder,
4659
475
    instructions: &mut Vec<Instruction>,
4660
475
) -> Result<()> {
4661
475
    builder.pop_operands(module, &[ValType::F64]);
4662
475
    builder.push_operands(&[ValType::F64]);
4663
475
    instructions.push(Instruction::F64Trunc);
4664
475
    Ok(())
4665
475
}
4666
4667
433
fn f64_nearest(
4668
433
    _: &mut Unstructured,
4669
433
    module: &Module,
4670
433
    builder: &mut CodeBuilder,
4671
433
    instructions: &mut Vec<Instruction>,
4672
433
) -> Result<()> {
4673
433
    builder.pop_operands(module, &[ValType::F64]);
4674
433
    builder.push_operands(&[ValType::F64]);
4675
433
    instructions.push(Instruction::F64Nearest);
4676
433
    Ok(())
4677
433
}
4678
4679
1.58k
fn f64_sqrt(
4680
1.58k
    _: &mut Unstructured,
4681
1.58k
    module: &Module,
4682
1.58k
    builder: &mut CodeBuilder,
4683
1.58k
    instructions: &mut Vec<Instruction>,
4684
1.58k
) -> Result<()> {
4685
1.58k
    builder.pop_operands(module, &[ValType::F64]);
4686
1.58k
    builder.push_operands(&[ValType::F64]);
4687
1.58k
    instructions.push(Instruction::F64Sqrt);
4688
1.58k
    Ok(())
4689
1.58k
}
4690
4691
64
fn f64_add(
4692
64
    _: &mut Unstructured,
4693
64
    module: &Module,
4694
64
    builder: &mut CodeBuilder,
4695
64
    instructions: &mut Vec<Instruction>,
4696
64
) -> Result<()> {
4697
64
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
4698
64
    builder.push_operands(&[ValType::F64]);
4699
64
    instructions.push(Instruction::F64Add);
4700
64
    Ok(())
4701
64
}
4702
4703
57
fn f64_sub(
4704
57
    _: &mut Unstructured,
4705
57
    module: &Module,
4706
57
    builder: &mut CodeBuilder,
4707
57
    instructions: &mut Vec<Instruction>,
4708
57
) -> Result<()> {
4709
57
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
4710
57
    builder.push_operands(&[ValType::F64]);
4711
57
    instructions.push(Instruction::F64Sub);
4712
57
    Ok(())
4713
57
}
4714
4715
63
fn f64_mul(
4716
63
    _: &mut Unstructured,
4717
63
    module: &Module,
4718
63
    builder: &mut CodeBuilder,
4719
63
    instructions: &mut Vec<Instruction>,
4720
63
) -> Result<()> {
4721
63
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
4722
63
    builder.push_operands(&[ValType::F64]);
4723
63
    instructions.push(Instruction::F64Mul);
4724
63
    Ok(())
4725
63
}
4726
4727
38
fn f64_div(
4728
38
    _: &mut Unstructured,
4729
38
    module: &Module,
4730
38
    builder: &mut CodeBuilder,
4731
38
    instructions: &mut Vec<Instruction>,
4732
38
) -> Result<()> {
4733
38
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
4734
38
    builder.push_operands(&[ValType::F64]);
4735
38
    instructions.push(Instruction::F64Div);
4736
38
    Ok(())
4737
38
}
4738
4739
43
fn f64_min(
4740
43
    _: &mut Unstructured,
4741
43
    module: &Module,
4742
43
    builder: &mut CodeBuilder,
4743
43
    instructions: &mut Vec<Instruction>,
4744
43
) -> Result<()> {
4745
43
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
4746
43
    builder.push_operands(&[ValType::F64]);
4747
43
    instructions.push(Instruction::F64Min);
4748
43
    Ok(())
4749
43
}
4750
4751
59
fn f64_max(
4752
59
    _: &mut Unstructured,
4753
59
    module: &Module,
4754
59
    builder: &mut CodeBuilder,
4755
59
    instructions: &mut Vec<Instruction>,
4756
59
) -> Result<()> {
4757
59
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
4758
59
    builder.push_operands(&[ValType::F64]);
4759
59
    instructions.push(Instruction::F64Max);
4760
59
    Ok(())
4761
59
}
4762
4763
103
fn f64_copysign(
4764
103
    _: &mut Unstructured,
4765
103
    module: &Module,
4766
103
    builder: &mut CodeBuilder,
4767
103
    instructions: &mut Vec<Instruction>,
4768
103
) -> Result<()> {
4769
103
    builder.pop_operands(module, &[ValType::F64, ValType::F64]);
4770
103
    builder.push_operands(&[ValType::F64]);
4771
103
    instructions.push(Instruction::F64Copysign);
4772
103
    Ok(())
4773
103
}
4774
4775
485
fn i32_wrap_i64(
4776
485
    _: &mut Unstructured,
4777
485
    module: &Module,
4778
485
    builder: &mut CodeBuilder,
4779
485
    instructions: &mut Vec<Instruction>,
4780
485
) -> Result<()> {
4781
485
    builder.pop_operands(module, &[ValType::I64]);
4782
485
    builder.push_operands(&[ValType::I32]);
4783
485
    instructions.push(Instruction::I32WrapI64);
4784
485
    Ok(())
4785
485
}
4786
4787
324k
fn nontrapping_f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
4788
324k
    module.config.saturating_float_to_int_enabled && f32_on_stack(module, builder)
4789
324k
}
4790
4791
516
fn i32_trunc_f32_s(
4792
516
    _: &mut Unstructured,
4793
516
    module: &Module,
4794
516
    builder: &mut CodeBuilder,
4795
516
    instructions: &mut Vec<Instruction>,
4796
516
) -> Result<()> {
4797
516
    builder.pop_operands(module, &[ValType::F32]);
4798
516
    builder.push_operands(&[ValType::I32]);
4799
516
    if module.config.disallow_traps {
4800
0
        no_traps::trunc(Instruction::I32TruncF32S, builder, instructions);
4801
516
    } else {
4802
516
        instructions.push(Instruction::I32TruncF32S);
4803
516
    }
4804
516
    Ok(())
4805
516
}
4806
4807
379
fn i32_trunc_f32_u(
4808
379
    _: &mut Unstructured,
4809
379
    module: &Module,
4810
379
    builder: &mut CodeBuilder,
4811
379
    instructions: &mut Vec<Instruction>,
4812
379
) -> Result<()> {
4813
379
    builder.pop_operands(module, &[ValType::F32]);
4814
379
    builder.push_operands(&[ValType::I32]);
4815
379
    if module.config.disallow_traps {
4816
0
        no_traps::trunc(Instruction::I32TruncF32U, builder, instructions);
4817
379
    } else {
4818
379
        instructions.push(Instruction::I32TruncF32U);
4819
379
    }
4820
379
    Ok(())
4821
379
}
4822
4823
324k
fn nontrapping_f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
4824
324k
    module.config.saturating_float_to_int_enabled && f64_on_stack(module, builder)
4825
324k
}
4826
4827
330
fn i32_trunc_f64_s(
4828
330
    _: &mut Unstructured,
4829
330
    module: &Module,
4830
330
    builder: &mut CodeBuilder,
4831
330
    instructions: &mut Vec<Instruction>,
4832
330
) -> Result<()> {
4833
330
    builder.pop_operands(module, &[ValType::F64]);
4834
330
    builder.push_operands(&[ValType::I32]);
4835
330
    if module.config.disallow_traps {
4836
0
        no_traps::trunc(Instruction::I32TruncF64S, builder, instructions);
4837
330
    } else {
4838
330
        instructions.push(Instruction::I32TruncF64S);
4839
330
    }
4840
330
    Ok(())
4841
330
}
4842
4843
488
fn i32_trunc_f64_u(
4844
488
    _: &mut Unstructured,
4845
488
    module: &Module,
4846
488
    builder: &mut CodeBuilder,
4847
488
    instructions: &mut Vec<Instruction>,
4848
488
) -> Result<()> {
4849
488
    builder.pop_operands(module, &[ValType::F64]);
4850
488
    builder.push_operands(&[ValType::I32]);
4851
488
    if module.config.disallow_traps {
4852
0
        no_traps::trunc(Instruction::I32TruncF64U, builder, instructions);
4853
488
    } else {
4854
488
        instructions.push(Instruction::I32TruncF64U);
4855
488
    }
4856
488
    Ok(())
4857
488
}
4858
4859
631
fn i64_extend_i32_s(
4860
631
    _: &mut Unstructured,
4861
631
    module: &Module,
4862
631
    builder: &mut CodeBuilder,
4863
631
    instructions: &mut Vec<Instruction>,
4864
631
) -> Result<()> {
4865
631
    builder.pop_operands(module, &[ValType::I32]);
4866
631
    builder.push_operands(&[ValType::I64]);
4867
631
    instructions.push(Instruction::I64ExtendI32S);
4868
631
    Ok(())
4869
631
}
4870
4871
547
fn i64_extend_i32_u(
4872
547
    _: &mut Unstructured,
4873
547
    module: &Module,
4874
547
    builder: &mut CodeBuilder,
4875
547
    instructions: &mut Vec<Instruction>,
4876
547
) -> Result<()> {
4877
547
    builder.pop_operands(module, &[ValType::I32]);
4878
547
    builder.push_operands(&[ValType::I64]);
4879
547
    instructions.push(Instruction::I64ExtendI32U);
4880
547
    Ok(())
4881
547
}
4882
4883
399
fn i64_trunc_f32_s(
4884
399
    _: &mut Unstructured,
4885
399
    module: &Module,
4886
399
    builder: &mut CodeBuilder,
4887
399
    instructions: &mut Vec<Instruction>,
4888
399
) -> Result<()> {
4889
399
    builder.pop_operands(module, &[ValType::F32]);
4890
399
    builder.push_operands(&[ValType::I64]);
4891
399
    if module.config.disallow_traps {
4892
0
        no_traps::trunc(Instruction::I64TruncF32S, builder, instructions);
4893
399
    } else {
4894
399
        instructions.push(Instruction::I64TruncF32S);
4895
399
    }
4896
399
    Ok(())
4897
399
}
4898
4899
124
fn i64_trunc_f32_u(
4900
124
    _: &mut Unstructured,
4901
124
    module: &Module,
4902
124
    builder: &mut CodeBuilder,
4903
124
    instructions: &mut Vec<Instruction>,
4904
124
) -> Result<()> {
4905
124
    builder.pop_operands(module, &[ValType::F32]);
4906
124
    builder.push_operands(&[ValType::I64]);
4907
124
    if module.config.disallow_traps {
4908
0
        no_traps::trunc(Instruction::I64TruncF32U, builder, instructions);
4909
124
    } else {
4910
124
        instructions.push(Instruction::I64TruncF32U);
4911
124
    }
4912
124
    Ok(())
4913
124
}
4914
4915
804
fn i64_trunc_f64_s(
4916
804
    _: &mut Unstructured,
4917
804
    module: &Module,
4918
804
    builder: &mut CodeBuilder,
4919
804
    instructions: &mut Vec<Instruction>,
4920
804
) -> Result<()> {
4921
804
    builder.pop_operands(module, &[ValType::F64]);
4922
804
    builder.push_operands(&[ValType::I64]);
4923
804
    if module.config.disallow_traps {
4924
0
        no_traps::trunc(Instruction::I64TruncF64S, builder, instructions);
4925
804
    } else {
4926
804
        instructions.push(Instruction::I64TruncF64S);
4927
804
    }
4928
804
    Ok(())
4929
804
}
4930
4931
242
fn i64_trunc_f64_u(
4932
242
    _: &mut Unstructured,
4933
242
    module: &Module,
4934
242
    builder: &mut CodeBuilder,
4935
242
    instructions: &mut Vec<Instruction>,
4936
242
) -> Result<()> {
4937
242
    builder.pop_operands(module, &[ValType::F64]);
4938
242
    builder.push_operands(&[ValType::I64]);
4939
242
    if module.config.disallow_traps {
4940
0
        no_traps::trunc(Instruction::I64TruncF64U, builder, instructions);
4941
242
    } else {
4942
242
        instructions.push(Instruction::I64TruncF64U);
4943
242
    }
4944
242
    Ok(())
4945
242
}
4946
4947
515
fn f32_convert_i32_s(
4948
515
    _: &mut Unstructured,
4949
515
    module: &Module,
4950
515
    builder: &mut CodeBuilder,
4951
515
    instructions: &mut Vec<Instruction>,
4952
515
) -> Result<()> {
4953
515
    builder.pop_operands(module, &[ValType::I32]);
4954
515
    builder.push_operands(&[ValType::F32]);
4955
515
    instructions.push(Instruction::F32ConvertI32S);
4956
515
    Ok(())
4957
515
}
4958
4959
375
fn f32_convert_i32_u(
4960
375
    _: &mut Unstructured,
4961
375
    module: &Module,
4962
375
    builder: &mut CodeBuilder,
4963
375
    instructions: &mut Vec<Instruction>,
4964
375
) -> Result<()> {
4965
375
    builder.pop_operands(module, &[ValType::I32]);
4966
375
    builder.push_operands(&[ValType::F32]);
4967
375
    instructions.push(Instruction::F32ConvertI32U);
4968
375
    Ok(())
4969
375
}
4970
4971
311
fn f32_convert_i64_s(
4972
311
    _: &mut Unstructured,
4973
311
    module: &Module,
4974
311
    builder: &mut CodeBuilder,
4975
311
    instructions: &mut Vec<Instruction>,
4976
311
) -> Result<()> {
4977
311
    builder.pop_operands(module, &[ValType::I64]);
4978
311
    builder.push_operands(&[ValType::F32]);
4979
311
    instructions.push(Instruction::F32ConvertI64S);
4980
311
    Ok(())
4981
311
}
4982
4983
615
fn f32_convert_i64_u(
4984
615
    _: &mut Unstructured,
4985
615
    module: &Module,
4986
615
    builder: &mut CodeBuilder,
4987
615
    instructions: &mut Vec<Instruction>,
4988
615
) -> Result<()> {
4989
615
    builder.pop_operands(module, &[ValType::I64]);
4990
615
    builder.push_operands(&[ValType::F32]);
4991
615
    instructions.push(Instruction::F32ConvertI64U);
4992
615
    Ok(())
4993
615
}
4994
4995
545
fn f32_demote_f64(
4996
545
    _: &mut Unstructured,
4997
545
    module: &Module,
4998
545
    builder: &mut CodeBuilder,
4999
545
    instructions: &mut Vec<Instruction>,
5000
545
) -> Result<()> {
5001
545
    builder.pop_operands(module, &[ValType::F64]);
5002
545
    builder.push_operands(&[ValType::F32]);
5003
545
    instructions.push(Instruction::F32DemoteF64);
5004
545
    Ok(())
5005
545
}
5006
5007
587
fn f64_convert_i32_s(
5008
587
    _: &mut Unstructured,
5009
587
    module: &Module,
5010
587
    builder: &mut CodeBuilder,
5011
587
    instructions: &mut Vec<Instruction>,
5012
587
) -> Result<()> {
5013
587
    builder.pop_operands(module, &[ValType::I32]);
5014
587
    builder.push_operands(&[ValType::F64]);
5015
587
    instructions.push(Instruction::F64ConvertI32S);
5016
587
    Ok(())
5017
587
}
5018
5019
479
fn f64_convert_i32_u(
5020
479
    _: &mut Unstructured,
5021
479
    module: &Module,
5022
479
    builder: &mut CodeBuilder,
5023
479
    instructions: &mut Vec<Instruction>,
5024
479
) -> Result<()> {
5025
479
    builder.pop_operands(module, &[ValType::I32]);
5026
479
    builder.push_operands(&[ValType::F64]);
5027
479
    instructions.push(Instruction::F64ConvertI32U);
5028
479
    Ok(())
5029
479
}
5030
5031
392
fn f64_convert_i64_s(
5032
392
    _: &mut Unstructured,
5033
392
    module: &Module,
5034
392
    builder: &mut CodeBuilder,
5035
392
    instructions: &mut Vec<Instruction>,
5036
392
) -> Result<()> {
5037
392
    builder.pop_operands(module, &[ValType::I64]);
5038
392
    builder.push_operands(&[ValType::F64]);
5039
392
    instructions.push(Instruction::F64ConvertI64S);
5040
392
    Ok(())
5041
392
}
5042
5043
902
fn f64_convert_i64_u(
5044
902
    _: &mut Unstructured,
5045
902
    module: &Module,
5046
902
    builder: &mut CodeBuilder,
5047
902
    instructions: &mut Vec<Instruction>,
5048
902
) -> Result<()> {
5049
902
    builder.pop_operands(module, &[ValType::I64]);
5050
902
    builder.push_operands(&[ValType::F64]);
5051
902
    instructions.push(Instruction::F64ConvertI64U);
5052
902
    Ok(())
5053
902
}
5054
5055
611
fn f64_promote_f32(
5056
611
    _: &mut Unstructured,
5057
611
    module: &Module,
5058
611
    builder: &mut CodeBuilder,
5059
611
    instructions: &mut Vec<Instruction>,
5060
611
) -> Result<()> {
5061
611
    builder.pop_operands(module, &[ValType::F32]);
5062
611
    builder.push_operands(&[ValType::F64]);
5063
611
    instructions.push(Instruction::F64PromoteF32);
5064
611
    Ok(())
5065
611
}
5066
5067
319
fn i32_reinterpret_f32(
5068
319
    _: &mut Unstructured,
5069
319
    module: &Module,
5070
319
    builder: &mut CodeBuilder,
5071
319
    instructions: &mut Vec<Instruction>,
5072
319
) -> Result<()> {
5073
319
    builder.pop_operands(module, &[ValType::F32]);
5074
319
    builder.push_operands(&[ValType::I32]);
5075
319
    instructions.push(Instruction::I32ReinterpretF32);
5076
319
    Ok(())
5077
319
}
5078
5079
140
fn i64_reinterpret_f64(
5080
140
    _: &mut Unstructured,
5081
140
    module: &Module,
5082
140
    builder: &mut CodeBuilder,
5083
140
    instructions: &mut Vec<Instruction>,
5084
140
) -> Result<()> {
5085
140
    builder.pop_operands(module, &[ValType::F64]);
5086
140
    builder.push_operands(&[ValType::I64]);
5087
140
    instructions.push(Instruction::I64ReinterpretF64);
5088
140
    Ok(())
5089
140
}
5090
5091
1.08k
fn f32_reinterpret_i32(
5092
1.08k
    _: &mut Unstructured,
5093
1.08k
    module: &Module,
5094
1.08k
    builder: &mut CodeBuilder,
5095
1.08k
    instructions: &mut Vec<Instruction>,
5096
1.08k
) -> Result<()> {
5097
1.08k
    builder.pop_operands(module, &[ValType::I32]);
5098
1.08k
    builder.push_operands(&[ValType::F32]);
5099
1.08k
    instructions.push(Instruction::F32ReinterpretI32);
5100
1.08k
    Ok(())
5101
1.08k
}
5102
5103
527
fn f64_reinterpret_i64(
5104
527
    _: &mut Unstructured,
5105
527
    module: &Module,
5106
527
    builder: &mut CodeBuilder,
5107
527
    instructions: &mut Vec<Instruction>,
5108
527
) -> Result<()> {
5109
527
    builder.pop_operands(module, &[ValType::I64]);
5110
527
    builder.push_operands(&[ValType::F64]);
5111
527
    instructions.push(Instruction::F64ReinterpretI64);
5112
527
    Ok(())
5113
527
}
5114
5115
162k
fn extendable_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
5116
162k
    module.config.sign_extension_ops_enabled && i32_on_stack(module, builder)
5117
162k
}
5118
5119
720
fn i32_extend_8_s(
5120
720
    _: &mut Unstructured,
5121
720
    module: &Module,
5122
720
    builder: &mut CodeBuilder,
5123
720
    instructions: &mut Vec<Instruction>,
5124
720
) -> Result<()> {
5125
720
    builder.pop_operands(module, &[ValType::I32]);
5126
720
    builder.push_operands(&[ValType::I32]);
5127
720
    instructions.push(Instruction::I32Extend8S);
5128
720
    Ok(())
5129
720
}
5130
5131
429
fn i32_extend_16_s(
5132
429
    _: &mut Unstructured,
5133
429
    module: &Module,
5134
429
    builder: &mut CodeBuilder,
5135
429
    instructions: &mut Vec<Instruction>,
5136
429
) -> Result<()> {
5137
429
    builder.pop_operands(module, &[ValType::I32]);
5138
429
    builder.push_operands(&[ValType::I32]);
5139
429
    instructions.push(Instruction::I32Extend16S);
5140
429
    Ok(())
5141
429
}
5142
5143
243k
fn extendable_i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
5144
243k
    module.config.sign_extension_ops_enabled && i64_on_stack(module, builder)
5145
243k
}
5146
5147
550
fn i64_extend_8_s(
5148
550
    _: &mut Unstructured,
5149
550
    module: &Module,
5150
550
    builder: &mut CodeBuilder,
5151
550
    instructions: &mut Vec<Instruction>,
5152
550
) -> Result<()> {
5153
550
    builder.pop_operands(module, &[ValType::I64]);
5154
550
    builder.push_operands(&[ValType::I64]);
5155
550
    instructions.push(Instruction::I64Extend8S);
5156
550
    Ok(())
5157
550
}
5158
5159
678
fn i64_extend_16_s(
5160
678
    _: &mut Unstructured,
5161
678
    module: &Module,
5162
678
    builder: &mut CodeBuilder,
5163
678
    instructions: &mut Vec<Instruction>,
5164
678
) -> Result<()> {
5165
678
    builder.pop_operands(module, &[ValType::I64]);
5166
678
    builder.push_operands(&[ValType::I64]);
5167
678
    instructions.push(Instruction::I64Extend16S);
5168
678
    Ok(())
5169
678
}
5170
5171
699
fn i64_extend_32_s(
5172
699
    _: &mut Unstructured,
5173
699
    module: &Module,
5174
699
    builder: &mut CodeBuilder,
5175
699
    instructions: &mut Vec<Instruction>,
5176
699
) -> Result<()> {
5177
699
    builder.pop_operands(module, &[ValType::I64]);
5178
699
    builder.push_operands(&[ValType::I64]);
5179
699
    instructions.push(Instruction::I64Extend32S);
5180
699
    Ok(())
5181
699
}
5182
5183
569
fn i32_trunc_sat_f32_s(
5184
569
    _: &mut Unstructured,
5185
569
    module: &Module,
5186
569
    builder: &mut CodeBuilder,
5187
569
    instructions: &mut Vec<Instruction>,
5188
569
) -> Result<()> {
5189
569
    builder.pop_operands(module, &[ValType::F32]);
5190
569
    builder.push_operands(&[ValType::I32]);
5191
569
    instructions.push(Instruction::I32TruncSatF32S);
5192
569
    Ok(())
5193
569
}
5194
5195
504
fn i32_trunc_sat_f32_u(
5196
504
    _: &mut Unstructured,
5197
504
    module: &Module,
5198
504
    builder: &mut CodeBuilder,
5199
504
    instructions: &mut Vec<Instruction>,
5200
504
) -> Result<()> {
5201
504
    builder.pop_operands(module, &[ValType::F32]);
5202
504
    builder.push_operands(&[ValType::I32]);
5203
504
    instructions.push(Instruction::I32TruncSatF32U);
5204
504
    Ok(())
5205
504
}
5206
5207
280
fn i32_trunc_sat_f64_s(
5208
280
    _: &mut Unstructured,
5209
280
    module: &Module,
5210
280
    builder: &mut CodeBuilder,
5211
280
    instructions: &mut Vec<Instruction>,
5212
280
) -> Result<()> {
5213
280
    builder.pop_operands(module, &[ValType::F64]);
5214
280
    builder.push_operands(&[ValType::I32]);
5215
280
    instructions.push(Instruction::I32TruncSatF64S);
5216
280
    Ok(())
5217
280
}
5218
5219
558
fn i32_trunc_sat_f64_u(
5220
558
    _: &mut Unstructured,
5221
558
    module: &Module,
5222
558
    builder: &mut CodeBuilder,
5223
558
    instructions: &mut Vec<Instruction>,
5224
558
) -> Result<()> {
5225
558
    builder.pop_operands(module, &[ValType::F64]);
5226
558
    builder.push_operands(&[ValType::I32]);
5227
558
    instructions.push(Instruction::I32TruncSatF64U);
5228
558
    Ok(())
5229
558
}
5230
5231
179
fn i64_trunc_sat_f32_s(
5232
179
    _: &mut Unstructured,
5233
179
    module: &Module,
5234
179
    builder: &mut CodeBuilder,
5235
179
    instructions: &mut Vec<Instruction>,
5236
179
) -> Result<()> {
5237
179
    builder.pop_operands(module, &[ValType::F32]);
5238
179
    builder.push_operands(&[ValType::I64]);
5239
179
    instructions.push(Instruction::I64TruncSatF32S);
5240
179
    Ok(())
5241
179
}
5242
5243
251
fn i64_trunc_sat_f32_u(
5244
251
    _: &mut Unstructured,
5245
251
    module: &Module,
5246
251
    builder: &mut CodeBuilder,
5247
251
    instructions: &mut Vec<Instruction>,
5248
251
) -> Result<()> {
5249
251
    builder.pop_operands(module, &[ValType::F32]);
5250
251
    builder.push_operands(&[ValType::I64]);
5251
251
    instructions.push(Instruction::I64TruncSatF32U);
5252
251
    Ok(())
5253
251
}
5254
5255
173
fn i64_trunc_sat_f64_s(
5256
173
    _: &mut Unstructured,
5257
173
    module: &Module,
5258
173
    builder: &mut CodeBuilder,
5259
173
    instructions: &mut Vec<Instruction>,
5260
173
) -> Result<()> {
5261
173
    builder.pop_operands(module, &[ValType::F64]);
5262
173
    builder.push_operands(&[ValType::I64]);
5263
173
    instructions.push(Instruction::I64TruncSatF64S);
5264
173
    Ok(())
5265
173
}
5266
5267
146
fn i64_trunc_sat_f64_u(
5268
146
    _: &mut Unstructured,
5269
146
    module: &Module,
5270
146
    builder: &mut CodeBuilder,
5271
146
    instructions: &mut Vec<Instruction>,
5272
146
) -> Result<()> {
5273
146
    builder.pop_operands(module, &[ValType::F64]);
5274
146
    builder.push_operands(&[ValType::I64]);
5275
146
    instructions.push(Instruction::I64TruncSatF64U);
5276
146
    Ok(())
5277
146
}
5278
5279
3.66k
fn memory_offset(u: &mut Unstructured, module: &Module, memory_index: u32) -> Result<u64> {
5280
3.66k
    let MemoryOffsetChoices(a, b, c) = module.config.memory_offset_choices;
5281
3.66k
    assert!(a + b + c != 0);
5282
5283
3.66k
    let memory_type = &module.memories[memory_index as usize];
5284
3.66k
    let min = memory_type
5285
3.66k
        .minimum
5286
3.66k
        .saturating_mul(crate::page_size(memory_type).into());
5287
3.66k
    let max = memory_type
5288
3.66k
        .maximum
5289
3.66k
        .map(|max| max.saturating_mul(crate::page_size(memory_type).into()))
5290
3.66k
        .unwrap_or(u64::MAX);
5291
5292
3.66k
    let (min, max, true_max) = match (memory_type.memory64, module.config.disallow_traps) {
5293
        (true, false) => {
5294
            // 64-bit memories can use the limits calculated above as-is
5295
0
            (min, max, u64::MAX)
5296
        }
5297
        (false, false) => {
5298
            // 32-bit memories can't represent a full 4gb offset, so if that's the
5299
            // min/max sizes then we need to switch the m to `u32::MAX`.
5300
3.66k
            (
5301
3.66k
                u64::from(u32::try_from(min).unwrap_or(u32::MAX)),
5302
3.66k
                u64::from(u32::try_from(max).unwrap_or(u32::MAX)),
5303
3.66k
                u64::from(u32::MAX),
5304
3.66k
            )
5305
        }
5306
        // The logic for non-trapping versions of load/store involves pushing
5307
        // the offset + load/store size onto the stack as either an i32 or i64
5308
        // value. So even though offsets can normally be as high as u32 or u64,
5309
        // we need to limit them to lower in order for our non-trapping logic to
5310
        // work. 16 is the number of bytes of the largest load type (V128).
5311
        (true, true) => {
5312
0
            let no_trap_max = (i64::MAX - 16) as u64;
5313
0
            (min.min(no_trap_max), no_trap_max, no_trap_max)
5314
        }
5315
        (false, true) => {
5316
0
            let no_trap_max = (i32::MAX - 16) as u64;
5317
0
            (min.min(no_trap_max), no_trap_max, no_trap_max)
5318
        }
5319
    };
5320
5321
3.66k
    let choice = u.int_in_range(0..=a + b + c - 1)?;
5322
3.66k
    if choice < a {
5323
3.49k
        u.int_in_range(0..=min)
5324
178
    } else if choice < a + b {
5325
144
        u.int_in_range(min..=max)
5326
    } else {
5327
34
        u.int_in_range(max..=true_max)
5328
    }
5329
3.66k
}
5330
5331
3.66k
fn mem_arg(
5332
3.66k
    u: &mut Unstructured,
5333
3.66k
    module: &Module,
5334
3.66k
    builder: &mut CodeBuilder,
5335
3.66k
    alignments: &[u32],
5336
3.66k
) -> Result<MemArg> {
5337
3.66k
    let memory_index = if builder.type_on_stack(module, ValType::I32) {
5338
3.66k
        builder.pop_operands(module, &[ValType::I32]);
5339
3.66k
        memory_index(u, builder, ValType::I32)?
5340
    } else {
5341
0
        builder.pop_operands(module, &[ValType::I64]);
5342
0
        memory_index(u, builder, ValType::I64)?
5343
    };
5344
3.66k
    let offset = memory_offset(u, module, memory_index)?;
5345
3.66k
    let align = *u.choose(alignments)?;
5346
3.66k
    Ok(MemArg {
5347
3.66k
        memory_index,
5348
3.66k
        offset,
5349
3.66k
        align,
5350
3.66k
    })
5351
3.66k
}
5352
5353
4.24k
fn memory_index(u: &mut Unstructured, builder: &CodeBuilder, ty: ValType) -> Result<u32> {
5354
4.24k
    if ty == ValType::I32 {
5355
4.24k
        Ok(*u.choose(&builder.allocs.memory32)?)
5356
    } else {
5357
0
        Ok(*u.choose(&builder.allocs.memory64)?)
5358
    }
5359
4.24k
}
5360
5361
0
fn data_index(u: &mut Unstructured, module: &Module) -> Result<u32> {
5362
0
    let data = module.data.len() as u32;
5363
0
    assert!(data > 0);
5364
0
    if data == 1 {
5365
0
        Ok(0)
5366
    } else {
5367
0
        u.int_in_range(0..=data - 1)
5368
    }
5369
0
}
5370
5371
#[inline]
5372
81.2k
fn ref_null_valid(module: &Module, _: &mut CodeBuilder) -> bool {
5373
81.2k
    module.config.reference_types_enabled
5374
81.2k
}
5375
5376
0
fn ref_null(
5377
0
    u: &mut Unstructured,
5378
0
    module: &Module,
5379
0
    builder: &mut CodeBuilder,
5380
0
    instructions: &mut Vec<Instruction>,
5381
0
) -> Result<()> {
5382
0
    let mut choices = vec![RefType::EXTERNREF, RefType::FUNCREF];
5383
0
    if module.config.exceptions_enabled {
5384
0
        choices.push(RefType::EXNREF);
5385
0
    }
5386
0
    if module.config.gc_enabled {
5387
0
        let r = |heap_type| RefType {
5388
0
            nullable: true,
5389
0
            heap_type,
5390
0
        };
5391
0
        choices.push(r(HeapType::Any));
5392
0
        choices.push(r(HeapType::Eq));
5393
0
        choices.push(r(HeapType::Array));
5394
0
        choices.push(r(HeapType::Struct));
5395
0
        choices.push(r(HeapType::I31));
5396
0
        choices.push(r(HeapType::None));
5397
0
        choices.push(r(HeapType::NoFunc));
5398
0
        choices.push(r(HeapType::NoExtern));
5399
0
        for i in 0..module.types.len() {
5400
0
            let i = u32::try_from(i).unwrap();
5401
0
            choices.push(r(HeapType::Concrete(i)));
5402
0
        }
5403
0
    }
5404
0
    let ty = *u.choose(&choices)?;
5405
0
    builder.push_operand(Some(ty.into()));
5406
0
    instructions.push(Instruction::RefNull(ty.heap_type));
5407
0
    Ok(())
5408
0
}
5409
5410
#[inline]
5411
81.2k
fn ref_func_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5412
81.2k
    module.config.reference_types_enabled && builder.allocs.referenced_functions.len() > 0
5413
81.2k
}
5414
5415
0
fn ref_func(
5416
0
    u: &mut Unstructured,
5417
0
    module: &Module,
5418
0
    builder: &mut CodeBuilder,
5419
0
    instructions: &mut Vec<Instruction>,
5420
0
) -> Result<()> {
5421
0
    let i = *u.choose(&builder.allocs.referenced_functions)?;
5422
0
    let ty = module.funcs[usize::try_from(i).unwrap()].0;
5423
0
    builder.push_operand(Some(ValType::Ref(if module.config.gc_enabled {
5424
0
        RefType {
5425
0
            nullable: false,
5426
0
            heap_type: HeapType::Concrete(ty),
5427
0
        }
5428
    } else {
5429
0
        RefType::FUNCREF
5430
    })));
5431
0
    instructions.push(Instruction::RefFunc(i));
5432
0
    Ok(())
5433
0
}
5434
5435
#[inline]
5436
81.2k
fn ref_as_non_null_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5437
81.2k
    module.config.gc_enabled && builder.ref_type_on_stack().is_some()
5438
81.2k
}
5439
5440
0
fn ref_as_non_null(
5441
0
    u: &mut Unstructured,
5442
0
    module: &Module,
5443
0
    builder: &mut CodeBuilder,
5444
0
    instructions: &mut Vec<Instruction>,
5445
0
) -> Result<()> {
5446
0
    let ref_ty = match builder.pop_ref_type() {
5447
0
        Some(r) => r,
5448
0
        None => module.arbitrary_ref_type(u)?,
5449
    };
5450
0
    builder.push_operand(Some(ValType::Ref(RefType {
5451
0
        nullable: false,
5452
0
        heap_type: ref_ty.heap_type,
5453
0
    })));
5454
0
    instructions.push(Instruction::RefAsNonNull);
5455
0
    Ok(())
5456
0
}
5457
5458
#[inline]
5459
81.2k
fn ref_eq_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5460
81.2k
    let eq_ref = ValType::Ref(RefType {
5461
81.2k
        nullable: true,
5462
81.2k
        heap_type: HeapType::Eq,
5463
81.2k
    });
5464
81.2k
    module.config.gc_enabled && builder.types_on_stack(module, &[eq_ref, eq_ref])
5465
81.2k
}
5466
5467
0
fn ref_eq(
5468
0
    _u: &mut Unstructured,
5469
0
    _module: &Module,
5470
0
    builder: &mut CodeBuilder,
5471
0
    instructions: &mut Vec<Instruction>,
5472
0
) -> Result<()> {
5473
0
    builder.pop_operand();
5474
0
    builder.pop_operand();
5475
0
    builder.push_operand(Some(ValType::I32));
5476
0
    instructions.push(Instruction::RefEq);
5477
0
    Ok(())
5478
0
}
5479
5480
#[inline]
5481
81.2k
fn ref_test_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5482
81.2k
    module.config.gc_enabled && builder.ref_type_on_stack().is_some()
5483
81.2k
}
5484
5485
0
fn ref_test(
5486
0
    u: &mut Unstructured,
5487
0
    module: &Module,
5488
0
    builder: &mut CodeBuilder,
5489
0
    instructions: &mut Vec<Instruction>,
5490
0
) -> Result<()> {
5491
0
    let ref_ty = match builder.pop_ref_type() {
5492
0
        Some(r) => r,
5493
0
        None => module.arbitrary_ref_type(u)?,
5494
    };
5495
0
    builder.push_operand(Some(ValType::I32));
5496
5497
0
    let sub_ty = module.arbitrary_matching_heap_type(u, ref_ty.heap_type)?;
5498
0
    instructions.push(if !ref_ty.nullable || u.arbitrary()? {
5499
0
        Instruction::RefTestNonNull(sub_ty)
5500
    } else {
5501
0
        Instruction::RefTestNullable(sub_ty)
5502
    });
5503
0
    Ok(())
5504
0
}
5505
5506
#[inline]
5507
81.2k
fn ref_cast_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5508
81.2k
    !module.config.disallow_traps
5509
81.2k
        && module.config.gc_enabled
5510
0
        && builder.ref_type_on_stack().is_some()
5511
81.2k
}
5512
5513
0
fn ref_cast(
5514
0
    u: &mut Unstructured,
5515
0
    module: &Module,
5516
0
    builder: &mut CodeBuilder,
5517
0
    instructions: &mut Vec<Instruction>,
5518
0
) -> Result<()> {
5519
0
    let ref_ty = match builder.pop_ref_type() {
5520
0
        Some(r) => r,
5521
0
        None => module.arbitrary_ref_type(u)?,
5522
    };
5523
0
    let sub_ty = RefType {
5524
0
        nullable: if !ref_ty.nullable {
5525
0
            false
5526
        } else {
5527
0
            u.arbitrary()?
5528
        },
5529
0
        heap_type: module.arbitrary_matching_heap_type(u, ref_ty.heap_type)?,
5530
    };
5531
0
    builder.push_operand(Some(ValType::Ref(sub_ty)));
5532
0
5533
0
    instructions.push(if !sub_ty.nullable {
5534
0
        Instruction::RefCastNonNull(sub_ty.heap_type)
5535
    } else {
5536
0
        Instruction::RefCastNullable(sub_ty.heap_type)
5537
    });
5538
0
    Ok(())
5539
0
}
5540
5541
#[inline]
5542
81.2k
fn ref_is_null_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5543
81.2k
    module.config.reference_types_enabled
5544
0
        && (builder.type_on_stack(module, ValType::EXTERNREF)
5545
0
            || builder.type_on_stack(module, ValType::FUNCREF))
5546
81.2k
}
5547
5548
0
fn ref_is_null(
5549
0
    _: &mut Unstructured,
5550
0
    _module: &Module,
5551
0
    builder: &mut CodeBuilder,
5552
0
    instructions: &mut Vec<Instruction>,
5553
0
) -> Result<()> {
5554
0
    builder.pop_ref_type();
5555
0
    builder.push_operands(&[ValType::I32]);
5556
0
    instructions.push(Instruction::RefIsNull);
5557
0
    Ok(())
5558
0
}
5559
5560
#[inline]
5561
81.2k
fn table_fill_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5562
81.2k
    module.config.reference_types_enabled
5563
0
        && module.config.bulk_memory_enabled
5564
0
        && !module.config.disallow_traps // Non-trapping table fill generation not yet implemented
5565
0
        && table_fill_candidates(module, builder).next().is_some()
5566
81.2k
}
5567
5568
0
fn table_fill_candidates<'a>(
5569
0
    module: &'a Module,
5570
0
    builder: &'a CodeBuilder,
5571
0
) -> impl Iterator<Item = u32> + 'a {
5572
0
    module
5573
0
        .tables
5574
0
        .iter()
5575
0
        .enumerate()
5576
0
        .filter(move |(_, t)| {
5577
0
            builder.types_on_stack(
5578
0
                module,
5579
0
                &[t.index_type(), t.element_type.into(), t.index_type()],
5580
0
            )
5581
0
        })
5582
0
        .map(|(i, _)| i as u32)
5583
0
}
5584
5585
0
fn table_fill(
5586
0
    u: &mut Unstructured,
5587
0
    module: &Module,
5588
0
    builder: &mut CodeBuilder,
5589
0
    instructions: &mut Vec<Instruction>,
5590
0
) -> Result<()> {
5591
0
    let table = *u.choose(&table_fill_candidates(module, builder).collect::<Vec<_>>())?;
5592
0
    let ty = &module.tables[table as usize];
5593
0
    builder.pop_operands(
5594
0
        module,
5595
0
        &[ty.index_type(), ty.element_type.into(), ty.index_type()],
5596
0
    );
5597
0
    instructions.push(Instruction::TableFill(table));
5598
0
    Ok(())
5599
0
}
5600
5601
#[inline]
5602
81.2k
fn table_set_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5603
81.2k
    module.config.reference_types_enabled
5604
0
    && !module.config.disallow_traps // Non-trapping table.set generation not yet implemented
5605
0
    && table_set_candidates(module, builder).next().is_some()
5606
81.2k
}
5607
5608
0
fn table_set_candidates<'a>(
5609
0
    module: &'a Module,
5610
0
    builder: &'a CodeBuilder,
5611
0
) -> impl Iterator<Item = u32> + 'a {
5612
0
    module
5613
0
        .tables
5614
0
        .iter()
5615
0
        .enumerate()
5616
0
        .filter(move |(_, t)| {
5617
0
            builder.types_on_stack(module, &[t.index_type(), t.element_type.into()])
5618
0
        })
5619
0
        .map(|(i, _)| i as u32)
5620
0
}
5621
5622
0
fn table_set(
5623
0
    u: &mut Unstructured,
5624
0
    module: &Module,
5625
0
    builder: &mut CodeBuilder,
5626
0
    instructions: &mut Vec<Instruction>,
5627
0
) -> Result<()> {
5628
0
    let table = *u.choose(&table_set_candidates(module, builder).collect::<Vec<_>>())?;
5629
0
    let ty = &module.tables[table as usize];
5630
0
    builder.pop_operands(module, &[ty.index_type(), ty.element_type.into()]);
5631
0
    instructions.push(Instruction::TableSet(table));
5632
0
    Ok(())
5633
0
}
5634
5635
#[inline]
5636
81.2k
fn table_get_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5637
81.2k
    if !module.config.reference_types_enabled {
5638
81.2k
        return false;
5639
0
    }
5640
0
    // Non-trapping table.get generation not yet implemented
5641
0
    if module.config.disallow_traps {
5642
0
        return false;
5643
0
    }
5644
0
    if builder.type_on_stack(module, ValType::I32) && builder.allocs.table32.len() > 0 {
5645
0
        return true;
5646
0
    }
5647
0
    if builder.type_on_stack(module, ValType::I64) && builder.allocs.table64.len() > 0 {
5648
0
        return true;
5649
0
    }
5650
0
    false
5651
81.2k
}
5652
5653
0
fn table_get(
5654
0
    u: &mut Unstructured,
5655
0
    module: &Module,
5656
0
    builder: &mut CodeBuilder,
5657
0
    instructions: &mut Vec<Instruction>,
5658
0
) -> Result<()> {
5659
0
    let candidates = if builder.type_on_stack(module, ValType::I32) {
5660
0
        builder.pop_operands(module, &[ValType::I32]);
5661
0
        &builder.allocs.table32
5662
    } else {
5663
0
        builder.pop_operands(module, &[ValType::I64]);
5664
0
        &builder.allocs.table64
5665
    };
5666
0
    let idx = *u.choose(candidates)?;
5667
0
    let ty = module.tables[idx as usize].element_type;
5668
0
    builder.push_operands(&[ty.into()]);
5669
0
    instructions.push(Instruction::TableGet(idx as u32));
5670
0
    Ok(())
5671
0
}
5672
5673
#[inline]
5674
81.2k
fn table_size_valid(module: &Module, _: &mut CodeBuilder) -> bool {
5675
81.2k
    module.config.reference_types_enabled && module.tables.len() > 0
5676
81.2k
}
5677
5678
0
fn table_size(
5679
0
    u: &mut Unstructured,
5680
0
    module: &Module,
5681
0
    builder: &mut CodeBuilder,
5682
0
    instructions: &mut Vec<Instruction>,
5683
0
) -> Result<()> {
5684
0
    let table = u.int_in_range(0..=module.tables.len() - 1)?;
5685
0
    let ty = &module.tables[table];
5686
0
    builder.push_operands(&[ty.index_type()]);
5687
0
    instructions.push(Instruction::TableSize(table as u32));
5688
0
    Ok(())
5689
0
}
5690
5691
#[inline]
5692
81.2k
fn table_grow_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5693
81.2k
    module.config.reference_types_enabled && table_grow_candidates(module, builder).next().is_some()
5694
81.2k
}
5695
5696
0
fn table_grow_candidates<'a>(
5697
0
    module: &'a Module,
5698
0
    builder: &'a CodeBuilder,
5699
0
) -> impl Iterator<Item = u32> + 'a {
5700
0
    module
5701
0
        .tables
5702
0
        .iter()
5703
0
        .enumerate()
5704
0
        .filter(move |(_, t)| {
5705
0
            builder.types_on_stack(module, &[t.element_type.into(), t.index_type()])
5706
0
        })
5707
0
        .map(|(i, _)| i as u32)
5708
0
}
5709
5710
0
fn table_grow(
5711
0
    u: &mut Unstructured,
5712
0
    module: &Module,
5713
0
    builder: &mut CodeBuilder,
5714
0
    instructions: &mut Vec<Instruction>,
5715
0
) -> Result<()> {
5716
0
    let table = *u.choose(&table_grow_candidates(module, builder).collect::<Vec<_>>())?;
5717
0
    let ty = &module.tables[table as usize];
5718
0
    builder.pop_operands(module, &[ty.element_type.into(), ty.index_type()]);
5719
0
    builder.push_operands(&[ty.index_type()]);
5720
0
    instructions.push(Instruction::TableGrow(table));
5721
0
    Ok(())
5722
0
}
5723
5724
#[inline]
5725
81.2k
fn table_copy_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5726
81.2k
    if !module.config.bulk_memory_enabled {
5727
81.2k
        return false;
5728
0
    }
5729
0
    // Non-trapping table.copy generation not yet implemented
5730
0
    if module.config.disallow_traps {
5731
0
        return false;
5732
0
    }
5733
0
    if builder.types_on_stack(module, &[ValType::I64, ValType::I64, ValType::I64]) {
5734
0
        return builder.allocs.table_copy_64_to_64.len() > 0;
5735
0
    }
5736
0
    if builder.types_on_stack(module, &[ValType::I32, ValType::I32, ValType::I32]) {
5737
0
        return builder.allocs.table_copy_32_to_32.len() > 0;
5738
0
    }
5739
0
    if builder.types_on_stack(module, &[ValType::I64, ValType::I32, ValType::I32]) {
5740
0
        return builder.allocs.table_copy_32_to_64.len() > 0;
5741
0
    }
5742
0
    if builder.types_on_stack(module, &[ValType::I32, ValType::I64, ValType::I32]) {
5743
0
        return builder.allocs.table_copy_64_to_32.len() > 0;
5744
0
    }
5745
0
    false
5746
81.2k
}
5747
5748
0
fn table_copy(
5749
0
    u: &mut Unstructured,
5750
0
    module: &Module,
5751
0
    builder: &mut CodeBuilder,
5752
0
    instructions: &mut Vec<Instruction>,
5753
0
) -> Result<()> {
5754
    use CopyIndexSize::*;
5755
5756
0
    let (src_table, dst_table) = match gen_copy_src_and_dst(module, builder) {
5757
0
        (I32, I32) => *u.choose(&builder.allocs.table_copy_32_to_32)?,
5758
0
        (I32, I64) => *u.choose(&builder.allocs.table_copy_32_to_64)?,
5759
0
        (I64, I32) => *u.choose(&builder.allocs.table_copy_64_to_32)?,
5760
0
        (I64, I64) => *u.choose(&builder.allocs.table_copy_64_to_64)?,
5761
    };
5762
0
    instructions.push(Instruction::TableCopy {
5763
0
        src_table,
5764
0
        dst_table,
5765
0
    });
5766
0
    Ok(())
5767
0
}
5768
5769
#[inline]
5770
81.2k
fn table_init_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5771
81.2k
    if !module.config.bulk_memory_enabled {
5772
81.2k
        return false;
5773
0
    }
5774
0
    // Non-trapping table.init generation not yet implemented.
5775
0
    if module.config.disallow_traps {
5776
0
        return false;
5777
0
    }
5778
0
    if builder.allocs.table32_init.len() > 0
5779
0
        && builder.types_on_stack(module, &[ValType::I32, ValType::I32, ValType::I32])
5780
    {
5781
0
        return true;
5782
0
    }
5783
0
    if builder.allocs.table64_init.len() > 0
5784
0
        && builder.types_on_stack(module, &[ValType::I64, ValType::I32, ValType::I32])
5785
    {
5786
0
        return true;
5787
0
    }
5788
0
    false
5789
81.2k
}
5790
5791
0
fn table_init(
5792
0
    u: &mut Unstructured,
5793
0
    module: &Module,
5794
0
    builder: &mut CodeBuilder,
5795
0
    instructions: &mut Vec<Instruction>,
5796
0
) -> Result<()> {
5797
0
    let candidates = if builder.types_on_stack(module, &[ValType::I64, ValType::I32, ValType::I32])
5798
    {
5799
0
        builder.pop_operands(module, &[ValType::I64, ValType::I32, ValType::I32]);
5800
0
        &builder.allocs.table64_init
5801
    } else {
5802
0
        builder.pop_operands(module, &[ValType::I32, ValType::I32, ValType::I32]);
5803
0
        &builder.allocs.table32_init
5804
    };
5805
0
    let (elem_index, table) = *u.choose(&candidates)?;
5806
0
    instructions.push(Instruction::TableInit { elem_index, table });
5807
0
    Ok(())
5808
0
}
5809
5810
#[inline]
5811
81.2k
fn elem_drop_valid(module: &Module, _builder: &mut CodeBuilder) -> bool {
5812
81.2k
    module.config.bulk_memory_enabled && module.elems.len() > 0
5813
81.2k
}
5814
5815
0
fn elem_drop(
5816
0
    u: &mut Unstructured,
5817
0
    module: &Module,
5818
0
    _builder: &mut CodeBuilder,
5819
0
    instructions: &mut Vec<Instruction>,
5820
0
) -> Result<()> {
5821
0
    let segment = u.int_in_range(0..=module.elems.len() - 1)? as u32;
5822
0
    instructions.push(Instruction::ElemDrop(segment));
5823
0
    Ok(())
5824
0
}
5825
5826
#[inline]
5827
81.2k
fn struct_new_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5828
81.2k
    module.config.gc_enabled
5829
0
        && module
5830
0
            .struct_types
5831
0
            .iter()
5832
0
            .copied()
5833
0
            .any(|i| builder.field_types_on_stack(module, &module.ty(i).unwrap_struct().fields))
5834
81.2k
}
5835
5836
0
fn struct_new(
5837
0
    u: &mut Unstructured,
5838
0
    module: &Module,
5839
0
    builder: &mut CodeBuilder,
5840
0
    instructions: &mut Vec<Instruction>,
5841
0
) -> Result<()> {
5842
0
    let n = module
5843
0
        .struct_types
5844
0
        .iter()
5845
0
        .filter(|i| builder.field_types_on_stack(module, &module.ty(**i).unwrap_struct().fields))
5846
0
        .count();
5847
0
    debug_assert!(n > 0);
5848
0
    let i = u.int_in_range(0..=n - 1)?;
5849
0
    let ty = module
5850
0
        .struct_types
5851
0
        .iter()
5852
0
        .copied()
5853
0
        .filter(|i| builder.field_types_on_stack(module, &module.ty(*i).unwrap_struct().fields))
5854
0
        .nth(i)
5855
0
        .unwrap();
5856
0
5857
0
    for _ in module.ty(ty).unwrap_struct().fields.iter() {
5858
0
        builder.pop_operand();
5859
0
    }
5860
0
    builder.push_operand(Some(ValType::Ref(RefType {
5861
0
        nullable: false,
5862
0
        heap_type: HeapType::Concrete(ty),
5863
0
    })));
5864
0
5865
0
    instructions.push(Instruction::StructNew(ty));
5866
0
    Ok(())
5867
0
}
5868
5869
#[inline]
5870
81.2k
fn struct_new_default_valid(module: &Module, _builder: &mut CodeBuilder) -> bool {
5871
81.2k
    module.config.gc_enabled
5872
0
        && module.struct_types.iter().copied().any(|i| {
5873
0
            module
5874
0
                .ty(i)
5875
0
                .unwrap_struct()
5876
0
                .fields
5877
0
                .iter()
5878
0
                .all(|f| f.element_type.is_defaultable())
5879
0
        })
5880
81.2k
}
5881
5882
0
fn struct_new_default(
5883
0
    u: &mut Unstructured,
5884
0
    module: &Module,
5885
0
    builder: &mut CodeBuilder,
5886
0
    instructions: &mut Vec<Instruction>,
5887
0
) -> Result<()> {
5888
0
    let n = module
5889
0
        .struct_types
5890
0
        .iter()
5891
0
        .filter(|i| {
5892
0
            module
5893
0
                .ty(**i)
5894
0
                .unwrap_struct()
5895
0
                .fields
5896
0
                .iter()
5897
0
                .all(|f| f.element_type.is_defaultable())
5898
0
        })
5899
0
        .count();
5900
0
    debug_assert!(n > 0);
5901
0
    let i = u.int_in_range(0..=n - 1)?;
5902
0
    let ty = module
5903
0
        .struct_types
5904
0
        .iter()
5905
0
        .copied()
5906
0
        .filter(|i| {
5907
0
            module
5908
0
                .ty(*i)
5909
0
                .unwrap_struct()
5910
0
                .fields
5911
0
                .iter()
5912
0
                .all(|f| f.element_type.is_defaultable())
5913
0
        })
5914
0
        .nth(i)
5915
0
        .unwrap();
5916
0
5917
0
    builder.push_operand(Some(ValType::Ref(RefType {
5918
0
        nullable: false,
5919
0
        heap_type: HeapType::Concrete(ty),
5920
0
    })));
5921
0
5922
0
    instructions.push(Instruction::StructNewDefault(ty));
5923
0
    Ok(())
5924
0
}
5925
5926
#[inline]
5927
81.2k
fn struct_get_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5928
81.2k
    module.config.gc_enabled
5929
0
        && !module.config.disallow_traps
5930
0
        && builder.non_empty_struct_ref_on_stack(module, !module.config.disallow_traps)
5931
81.2k
}
5932
5933
0
fn struct_get(
5934
0
    u: &mut Unstructured,
5935
0
    module: &Module,
5936
0
    builder: &mut CodeBuilder,
5937
0
    instructions: &mut Vec<Instruction>,
5938
0
) -> Result<()> {
5939
0
    let (_, struct_type_index) = builder.pop_concrete_ref_type();
5940
0
    let struct_ty = module.ty(struct_type_index).unwrap_struct();
5941
0
    let num_fields = u32::try_from(struct_ty.fields.len()).unwrap();
5942
0
    debug_assert!(num_fields > 0);
5943
0
    let field_index = u.int_in_range(0..=num_fields - 1)?;
5944
0
    let (val_ty, ext) = match struct_ty.fields[usize::try_from(field_index).unwrap()].element_type {
5945
0
        StorageType::I8 | StorageType::I16 => (ValType::I32, Some(u.arbitrary()?)),
5946
0
        StorageType::Val(v) => (v, None),
5947
    };
5948
0
    builder.push_operand(Some(val_ty));
5949
0
    instructions.push(match ext {
5950
0
        None => Instruction::StructGet {
5951
0
            struct_type_index,
5952
0
            field_index,
5953
0
        },
5954
0
        Some(true) => Instruction::StructGetS {
5955
0
            struct_type_index,
5956
0
            field_index,
5957
0
        },
5958
0
        Some(false) => Instruction::StructGetU {
5959
0
            struct_type_index,
5960
0
            field_index,
5961
0
        },
5962
    });
5963
0
    Ok(())
5964
0
}
5965
5966
#[inline]
5967
81.2k
fn struct_set_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
5968
81.2k
    if !module.config.gc_enabled {
5969
81.2k
        return false;
5970
0
    }
5971
0
    match builder.concrete_struct_ref_type_on_stack_at(module, 1) {
5972
0
        None => return false,
5973
0
        Some((true, _, _)) if module.config.disallow_traps => return false,
5974
0
        Some((_, _, ty)) => ty
5975
0
            .fields
5976
0
            .iter()
5977
0
            .any(|f| f.mutable && builder.type_on_stack(module, f.element_type.unpack())),
5978
    }
5979
81.2k
}
5980
5981
0
fn struct_set(
5982
0
    u: &mut Unstructured,
5983
0
    module: &Module,
5984
0
    builder: &mut CodeBuilder,
5985
0
    instructions: &mut Vec<Instruction>,
5986
0
) -> Result<()> {
5987
0
    let val_ty = builder.pop_operand();
5988
0
    let (_, struct_type_index) = builder.pop_concrete_ref_type();
5989
0
    let struct_ty = module.ty(struct_type_index).unwrap_struct();
5990
0
5991
0
    let valid_field = |f: &FieldType| -> bool {
5992
0
        match val_ty {
5993
0
            None => f.mutable,
5994
0
            Some(val_ty) => {
5995
0
                f.mutable && module.val_type_is_sub_type(val_ty, f.element_type.unpack())
5996
            }
5997
        }
5998
0
    };
5999
6000
0
    let n = struct_ty.fields.iter().filter(|f| valid_field(f)).count();
6001
0
    debug_assert!(n > 0);
6002
0
    let i = u.int_in_range(0..=n - 1)?;
6003
0
    let (field_index, _) = struct_ty
6004
0
        .fields
6005
0
        .iter()
6006
0
        .enumerate()
6007
0
        .filter(|(_, f)| valid_field(f))
6008
0
        .nth(i)
6009
0
        .unwrap();
6010
0
    let field_index = u32::try_from(field_index).unwrap();
6011
0
6012
0
    instructions.push(Instruction::StructSet {
6013
0
        struct_type_index,
6014
0
        field_index,
6015
0
    });
6016
0
    Ok(())
6017
0
}
6018
6019
#[inline]
6020
81.2k
fn array_new_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6021
81.2k
    module.config.gc_enabled
6022
0
        && builder.type_on_stack(module, ValType::I32)
6023
0
        && module
6024
0
            .array_types
6025
0
            .iter()
6026
0
            .any(|i| builder.field_type_on_stack_at(module, 1, module.ty(*i).unwrap_array().0))
6027
81.2k
}
6028
6029
0
fn array_new(
6030
0
    u: &mut Unstructured,
6031
0
    module: &Module,
6032
0
    builder: &mut CodeBuilder,
6033
0
    instructions: &mut Vec<Instruction>,
6034
0
) -> Result<()> {
6035
0
    let n = module
6036
0
        .array_types
6037
0
        .iter()
6038
0
        .filter(|i| builder.field_type_on_stack_at(module, 1, module.ty(**i).unwrap_array().0))
6039
0
        .count();
6040
0
    debug_assert!(n > 0);
6041
0
    let i = u.int_in_range(0..=n - 1)?;
6042
0
    let ty = module
6043
0
        .array_types
6044
0
        .iter()
6045
0
        .copied()
6046
0
        .filter(|i| builder.field_type_on_stack_at(module, 1, module.ty(*i).unwrap_array().0))
6047
0
        .nth(i)
6048
0
        .unwrap();
6049
0
6050
0
    builder.pop_operand();
6051
0
    builder.pop_operand();
6052
0
    builder.push_operand(Some(ValType::Ref(RefType {
6053
0
        nullable: false,
6054
0
        heap_type: HeapType::Concrete(ty),
6055
0
    })));
6056
0
6057
0
    instructions.push(Instruction::ArrayNew(ty));
6058
0
    Ok(())
6059
0
}
6060
6061
#[inline]
6062
81.2k
fn array_new_fixed_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6063
81.2k
    module.config.gc_enabled
6064
0
        && module
6065
0
            .array_types
6066
0
            .iter()
6067
0
            .any(|i| builder.field_type_on_stack(module, module.ty(*i).unwrap_array().0))
6068
81.2k
}
6069
6070
0
fn array_new_fixed(
6071
0
    u: &mut Unstructured,
6072
0
    module: &Module,
6073
0
    builder: &mut CodeBuilder,
6074
0
    instructions: &mut Vec<Instruction>,
6075
0
) -> Result<()> {
6076
0
    let n = module
6077
0
        .array_types
6078
0
        .iter()
6079
0
        .filter(|i| builder.field_type_on_stack(module, module.ty(**i).unwrap_array().0))
6080
0
        .count();
6081
0
    debug_assert!(n > 0);
6082
0
    let i = u.int_in_range(0..=n - 1)?;
6083
0
    let array_type_index = module
6084
0
        .array_types
6085
0
        .iter()
6086
0
        .copied()
6087
0
        .filter(|i| builder.field_type_on_stack(module, module.ty(*i).unwrap_array().0))
6088
0
        .nth(i)
6089
0
        .unwrap();
6090
0
    let elem_ty = module
6091
0
        .ty(array_type_index)
6092
0
        .unwrap_array()
6093
0
        .0
6094
0
        .element_type
6095
0
        .unpack();
6096
0
6097
0
    let m = (0..builder.operands().len())
6098
0
        .take_while(|i| builder.type_on_stack_at(module, *i, elem_ty))
6099
0
        .count();
6100
0
    debug_assert!(m > 0);
6101
0
    let array_size = u.int_in_range(0..=m - 1)?;
6102
0
    let array_size = u32::try_from(array_size).unwrap();
6103
0
6104
0
    for _ in 0..array_size {
6105
0
        builder.pop_operand();
6106
0
    }
6107
0
    builder.push_operand(Some(ValType::Ref(RefType {
6108
0
        nullable: false,
6109
0
        heap_type: HeapType::Concrete(array_type_index),
6110
0
    })));
6111
0
6112
0
    instructions.push(Instruction::ArrayNewFixed {
6113
0
        array_type_index,
6114
0
        array_size,
6115
0
    });
6116
0
    Ok(())
6117
0
}
6118
6119
#[inline]
6120
81.2k
fn array_new_default_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6121
81.2k
    module.config.gc_enabled
6122
0
        && builder.type_on_stack(module, ValType::I32)
6123
0
        && module
6124
0
            .array_types
6125
0
            .iter()
6126
0
            .any(|i| module.ty(*i).unwrap_array().0.element_type.is_defaultable())
6127
81.2k
}
6128
6129
0
fn array_new_default(
6130
0
    u: &mut Unstructured,
6131
0
    module: &Module,
6132
0
    builder: &mut CodeBuilder,
6133
0
    instructions: &mut Vec<Instruction>,
6134
0
) -> Result<()> {
6135
0
    let n = module
6136
0
        .array_types
6137
0
        .iter()
6138
0
        .filter(|i| {
6139
0
            module
6140
0
                .ty(**i)
6141
0
                .unwrap_array()
6142
0
                .0
6143
0
                .element_type
6144
0
                .is_defaultable()
6145
0
        })
6146
0
        .count();
6147
0
    debug_assert!(n > 0);
6148
0
    let i = u.int_in_range(0..=n - 1)?;
6149
0
    let array_type_index = module
6150
0
        .array_types
6151
0
        .iter()
6152
0
        .copied()
6153
0
        .filter(|i| module.ty(*i).unwrap_array().0.element_type.is_defaultable())
6154
0
        .nth(i)
6155
0
        .unwrap();
6156
0
6157
0
    builder.pop_operand();
6158
0
    builder.push_operand(Some(ValType::Ref(RefType {
6159
0
        nullable: false,
6160
0
        heap_type: HeapType::Concrete(array_type_index),
6161
0
    })));
6162
0
    instructions.push(Instruction::ArrayNewDefault(array_type_index));
6163
0
    Ok(())
6164
0
}
6165
6166
#[inline]
6167
81.2k
fn array_new_data_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6168
81.2k
    module.config.gc_enabled
6169
0
        && module.config.bulk_memory_enabled // Requires data count section
6170
0
        && !module.config.disallow_traps
6171
0
        && !module.data.is_empty()
6172
0
        && builder.types_on_stack(module, &[ValType::I32, ValType::I32])
6173
0
        && module.array_types.iter().any(|i| {
6174
0
            let ty = module.ty(*i).unwrap_array().0.element_type.unpack();
6175
0
            ty.is_numeric() | ty.is_vector()
6176
0
        })
6177
81.2k
}
6178
6179
0
fn array_new_data(
6180
0
    u: &mut Unstructured,
6181
0
    module: &Module,
6182
0
    builder: &mut CodeBuilder,
6183
0
    instructions: &mut Vec<Instruction>,
6184
0
) -> Result<()> {
6185
0
    let n = module
6186
0
        .array_types
6187
0
        .iter()
6188
0
        .filter(|i| {
6189
0
            let ty = module.ty(**i).unwrap_array().0.element_type.unpack();
6190
0
            ty.is_numeric() | ty.is_vector()
6191
0
        })
6192
0
        .count();
6193
0
    debug_assert!(n > 0);
6194
0
    let i = u.int_in_range(0..=n - 1)?;
6195
0
    let array_type_index = module
6196
0
        .array_types
6197
0
        .iter()
6198
0
        .copied()
6199
0
        .filter(|i| {
6200
0
            let ty = module.ty(*i).unwrap_array().0.element_type.unpack();
6201
0
            ty.is_numeric() | ty.is_vector()
6202
0
        })
6203
0
        .nth(i)
6204
0
        .unwrap();
6205
0
6206
0
    let m = module.data.len();
6207
0
    debug_assert!(m > 0);
6208
0
    let array_data_index = u.int_in_range(0..=m - 1)?;
6209
0
    let array_data_index = u32::try_from(array_data_index).unwrap();
6210
0
6211
0
    builder.pop_operand();
6212
0
    builder.pop_operand();
6213
0
    builder.push_operand(Some(ValType::Ref(RefType {
6214
0
        nullable: false,
6215
0
        heap_type: HeapType::Concrete(array_type_index),
6216
0
    })));
6217
0
    instructions.push(Instruction::ArrayNewData {
6218
0
        array_type_index,
6219
0
        array_data_index,
6220
0
    });
6221
0
    Ok(())
6222
0
}
6223
6224
0
fn module_has_elem_segment_of_array_type(module: &Module, ty: &ArrayType) -> bool {
6225
0
    module
6226
0
        .elems
6227
0
        .iter()
6228
0
        .any(|elem| module.val_type_is_sub_type(ValType::Ref(elem.ty), ty.0.element_type.unpack()))
6229
0
}
6230
6231
#[inline]
6232
81.2k
fn array_new_elem_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6233
81.2k
    module.config.gc_enabled
6234
0
        && !module.config.disallow_traps
6235
0
        && builder.types_on_stack(module, &[ValType::I32, ValType::I32])
6236
0
        && module
6237
0
            .array_types
6238
0
            .iter()
6239
0
            .any(|i| module_has_elem_segment_of_array_type(module, module.ty(*i).unwrap_array()))
6240
81.2k
}
6241
6242
0
fn array_new_elem(
6243
0
    u: &mut Unstructured,
6244
0
    module: &Module,
6245
0
    builder: &mut CodeBuilder,
6246
0
    instructions: &mut Vec<Instruction>,
6247
0
) -> Result<()> {
6248
0
    let n = module
6249
0
        .array_types
6250
0
        .iter()
6251
0
        .filter(|i| module_has_elem_segment_of_array_type(module, module.ty(**i).unwrap_array()))
6252
0
        .count();
6253
0
    debug_assert!(n > 0);
6254
0
    let i = u.int_in_range(0..=n - 1)?;
6255
0
    let array_type_index = module
6256
0
        .array_types
6257
0
        .iter()
6258
0
        .copied()
6259
0
        .filter(|i| module_has_elem_segment_of_array_type(module, module.ty(*i).unwrap_array()))
6260
0
        .nth(i)
6261
0
        .unwrap();
6262
0
    let elem_ty = module
6263
0
        .ty(array_type_index)
6264
0
        .unwrap_array()
6265
0
        .0
6266
0
        .element_type
6267
0
        .unpack();
6268
0
6269
0
    let m = module
6270
0
        .elems
6271
0
        .iter()
6272
0
        .filter(|elem| module.val_type_is_sub_type(ValType::Ref(elem.ty), elem_ty))
6273
0
        .count();
6274
0
    debug_assert!(m > 0);
6275
0
    let j = u.int_in_range(0..=m - 1)?;
6276
0
    let (array_elem_index, _) = module
6277
0
        .elems
6278
0
        .iter()
6279
0
        .enumerate()
6280
0
        .filter(|(_, elem)| module.val_type_is_sub_type(ValType::Ref(elem.ty), elem_ty))
6281
0
        .nth(j)
6282
0
        .unwrap();
6283
0
    let array_elem_index = u32::try_from(array_elem_index).unwrap();
6284
0
6285
0
    builder.pop_operand();
6286
0
    builder.pop_operand();
6287
0
    builder.push_operand(Some(ValType::Ref(RefType {
6288
0
        nullable: false,
6289
0
        heap_type: HeapType::Concrete(array_type_index),
6290
0
    })));
6291
0
6292
0
    instructions.push(Instruction::ArrayNewElem {
6293
0
        array_type_index,
6294
0
        array_elem_index,
6295
0
    });
6296
0
    Ok(())
6297
0
}
6298
6299
#[inline]
6300
81.2k
fn array_get_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6301
81.2k
    module.config.gc_enabled
6302
0
        && !module.config.disallow_traps // TODO: add support for disallowing traps
6303
0
        && builder.type_on_stack(module, ValType::I32)
6304
0
        && builder.concrete_array_ref_type_on_stack_at(module, 1).is_some()
6305
81.2k
}
6306
6307
0
fn array_get(
6308
0
    u: &mut Unstructured,
6309
0
    module: &Module,
6310
0
    builder: &mut CodeBuilder,
6311
0
    instructions: &mut Vec<Instruction>,
6312
0
) -> Result<()> {
6313
0
    builder.pop_operand();
6314
0
    let (_, array_type_index) = builder.pop_concrete_ref_type();
6315
0
    let elem_ty = module.ty(array_type_index).unwrap_array().0.element_type;
6316
0
    builder.push_operand(Some(elem_ty.unpack()));
6317
0
    instructions.push(match elem_ty {
6318
        StorageType::I8 | StorageType::I16 => {
6319
0
            if u.arbitrary()? {
6320
0
                Instruction::ArrayGetS(array_type_index)
6321
            } else {
6322
0
                Instruction::ArrayGetU(array_type_index)
6323
            }
6324
        }
6325
0
        StorageType::Val(_) => Instruction::ArrayGet(array_type_index),
6326
    });
6327
0
    Ok(())
6328
0
}
6329
6330
#[inline]
6331
81.2k
fn array_set_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6332
81.2k
    if !module.config.gc_enabled
6333
        // TODO: implement disallowing traps.
6334
0
        || module.config.disallow_traps
6335
0
        || !builder.type_on_stack_at(module, 1, ValType::I32)
6336
    {
6337
81.2k
        return false;
6338
0
    }
6339
0
    match builder.concrete_array_ref_type_on_stack_at(module, 2) {
6340
0
        None => false,
6341
0
        Some((_nullable, _idx, array_ty)) => {
6342
0
            array_ty.0.mutable && builder.field_type_on_stack(module, array_ty.0)
6343
        }
6344
    }
6345
81.2k
}
6346
6347
0
fn array_set(
6348
0
    _u: &mut Unstructured,
6349
0
    _module: &Module,
6350
0
    builder: &mut CodeBuilder,
6351
0
    instructions: &mut Vec<Instruction>,
6352
0
) -> Result<()> {
6353
0
    builder.pop_operand();
6354
0
    builder.pop_operand();
6355
0
    let (_, ty) = builder.pop_concrete_ref_type();
6356
0
    instructions.push(Instruction::ArraySet(ty));
6357
0
    Ok(())
6358
0
}
6359
6360
#[inline]
6361
81.2k
fn array_len_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6362
81.2k
    module.config.gc_enabled
6363
0
        && builder.type_on_stack(
6364
0
            module,
6365
0
            ValType::Ref(RefType {
6366
0
                nullable: true,
6367
0
                heap_type: HeapType::Array,
6368
0
            }),
6369
0
        )
6370
81.2k
}
6371
6372
0
fn array_len(
6373
0
    _u: &mut Unstructured,
6374
0
    _module: &Module,
6375
0
    builder: &mut CodeBuilder,
6376
0
    instructions: &mut Vec<Instruction>,
6377
0
) -> Result<()> {
6378
0
    builder.pop_operand();
6379
0
    builder.push_operand(Some(ValType::I32));
6380
0
    instructions.push(Instruction::ArrayLen);
6381
0
    Ok(())
6382
0
}
6383
6384
#[inline]
6385
81.2k
fn array_fill_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6386
81.2k
    if !module.config.gc_enabled
6387
        // TODO: add support for disallowing traps
6388
0
        || module.config.disallow_traps
6389
0
        || !builder.type_on_stack_at(module, 0, ValType::I32)
6390
0
        || !builder.type_on_stack_at(module, 2, ValType::I32)
6391
    {
6392
81.2k
        return false;
6393
0
    }
6394
0
    match builder.concrete_array_ref_type_on_stack_at(module, 3) {
6395
0
        None => return false,
6396
0
        Some((_, _, array_ty)) => {
6397
0
            array_ty.0.mutable && builder.field_type_on_stack_at(module, 1, array_ty.0)
6398
        }
6399
    }
6400
81.2k
}
6401
6402
0
fn array_fill(
6403
0
    _u: &mut Unstructured,
6404
0
    _module: &Module,
6405
0
    builder: &mut CodeBuilder,
6406
0
    instructions: &mut Vec<Instruction>,
6407
0
) -> Result<()> {
6408
0
    builder.pop_operand();
6409
0
    builder.pop_operand();
6410
0
    builder.pop_operand();
6411
0
    let (_, ty) = builder.pop_concrete_ref_type();
6412
0
    instructions.push(Instruction::ArrayFill(ty));
6413
0
    Ok(())
6414
0
}
6415
6416
#[inline]
6417
81.2k
fn array_copy_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6418
81.2k
    if !module.config.gc_enabled
6419
        // TODO: add support for disallowing traps
6420
0
        || module.config.disallow_traps
6421
0
        || !builder.type_on_stack_at(module, 0, ValType::I32)
6422
0
        || !builder.type_on_stack_at(module, 1, ValType::I32)
6423
0
        || !builder.type_on_stack_at(module, 3, ValType::I32)
6424
    {
6425
81.2k
        return false;
6426
0
    }
6427
0
    let x = match builder.concrete_array_ref_type_on_stack_at(module, 4) {
6428
0
        None => return false,
6429
0
        Some((_, _, x)) => x,
6430
0
    };
6431
0
    if !x.0.mutable {
6432
0
        return false;
6433
0
    }
6434
0
    let y = match builder.concrete_array_ref_type_on_stack_at(module, 2) {
6435
0
        None => return false,
6436
0
        Some((_, _, y)) => y,
6437
0
    };
6438
0
    match (x.0.element_type, y.0.element_type) {
6439
0
        (StorageType::I8, StorageType::I8) => true,
6440
0
        (StorageType::I8, _) => false,
6441
0
        (StorageType::I16, StorageType::I16) => true,
6442
0
        (StorageType::I16, _) => false,
6443
0
        (StorageType::Val(x), StorageType::Val(y)) => module.val_type_is_sub_type(y, x),
6444
0
        (StorageType::Val(_), _) => false,
6445
    }
6446
81.2k
}
6447
6448
0
fn array_copy(
6449
0
    _u: &mut Unstructured,
6450
0
    _module: &Module,
6451
0
    builder: &mut CodeBuilder,
6452
0
    instructions: &mut Vec<Instruction>,
6453
0
) -> Result<()> {
6454
0
    builder.pop_operand();
6455
0
    builder.pop_operand();
6456
0
    let (_, array_type_index_src) = builder.pop_concrete_ref_type();
6457
0
    builder.pop_operand();
6458
0
    let (_, array_type_index_dst) = builder.pop_concrete_ref_type();
6459
0
    instructions.push(Instruction::ArrayCopy {
6460
0
        array_type_index_dst,
6461
0
        array_type_index_src,
6462
0
    });
6463
0
    Ok(())
6464
0
}
6465
6466
#[inline]
6467
81.2k
fn array_init_data_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6468
81.2k
    if !module.config.gc_enabled
6469
0
        || !module.config.bulk_memory_enabled // Requires data count section
6470
0
        || module.config.disallow_traps
6471
0
        || module.data.is_empty()
6472
0
        || !builder.types_on_stack(module, &[ValType::I32, ValType::I32, ValType::I32])
6473
    {
6474
81.2k
        return false;
6475
0
    }
6476
0
    match builder.concrete_array_ref_type_on_stack_at(module, 3) {
6477
0
        None => return false,
6478
0
        Some((_, _, ty)) => {
6479
0
            let elem_ty = ty.0.element_type.unpack();
6480
0
            ty.0.mutable && (elem_ty.is_numeric() || elem_ty.is_vector())
6481
        }
6482
    }
6483
81.2k
}
6484
6485
0
fn array_init_data(
6486
0
    u: &mut Unstructured,
6487
0
    module: &Module,
6488
0
    builder: &mut CodeBuilder,
6489
0
    instructions: &mut Vec<Instruction>,
6490
0
) -> Result<()> {
6491
0
    builder.pop_operand();
6492
0
    builder.pop_operand();
6493
0
    builder.pop_operand();
6494
0
    let (_, array_type_index) = builder.pop_concrete_ref_type();
6495
0
6496
0
    let n = module.data.len();
6497
0
    debug_assert!(n > 0);
6498
0
    let array_data_index = u.int_in_range(0..=n - 1)?;
6499
0
    let array_data_index = u32::try_from(array_data_index).unwrap();
6500
0
6501
0
    instructions.push(Instruction::ArrayInitData {
6502
0
        array_type_index,
6503
0
        array_data_index,
6504
0
    });
6505
0
    Ok(())
6506
0
}
6507
6508
#[inline]
6509
81.2k
fn array_init_elem_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6510
81.2k
    if !module.config.gc_enabled
6511
0
        || module.config.disallow_traps
6512
0
        || !builder.types_on_stack(module, &[ValType::I32, ValType::I32, ValType::I32])
6513
    {
6514
81.2k
        return false;
6515
0
    }
6516
0
    match builder.concrete_array_ref_type_on_stack_at(module, 3) {
6517
0
        None => return false,
6518
0
        Some((_, _, array_ty)) => {
6519
0
            array_ty.0.mutable && module_has_elem_segment_of_array_type(module, &array_ty)
6520
        }
6521
    }
6522
81.2k
}
6523
6524
0
fn array_init_elem(
6525
0
    u: &mut Unstructured,
6526
0
    module: &Module,
6527
0
    builder: &mut CodeBuilder,
6528
0
    instructions: &mut Vec<Instruction>,
6529
0
) -> Result<()> {
6530
0
    builder.pop_operand();
6531
0
    builder.pop_operand();
6532
0
    builder.pop_operand();
6533
0
    let (_, array_type_index) = builder.pop_concrete_ref_type();
6534
0
6535
0
    let elem_ty = module
6536
0
        .ty(array_type_index)
6537
0
        .unwrap_array()
6538
0
        .0
6539
0
        .element_type
6540
0
        .unpack();
6541
0
6542
0
    let n = module
6543
0
        .elems
6544
0
        .iter()
6545
0
        .filter(|elem| module.val_type_is_sub_type(ValType::Ref(elem.ty), elem_ty))
6546
0
        .count();
6547
0
    debug_assert!(n > 0);
6548
0
    let j = u.int_in_range(0..=n - 1)?;
6549
0
    let (array_elem_index, _) = module
6550
0
        .elems
6551
0
        .iter()
6552
0
        .enumerate()
6553
0
        .filter(|(_, elem)| module.val_type_is_sub_type(ValType::Ref(elem.ty), elem_ty))
6554
0
        .nth(j)
6555
0
        .unwrap();
6556
0
    let array_elem_index = u32::try_from(array_elem_index).unwrap();
6557
0
6558
0
    instructions.push(Instruction::ArrayInitElem {
6559
0
        array_type_index,
6560
0
        array_elem_index,
6561
0
    });
6562
0
    Ok(())
6563
0
}
6564
6565
#[inline]
6566
81.2k
fn ref_i31_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6567
81.2k
    module.config.gc_enabled && builder.type_on_stack(module, ValType::I32)
6568
81.2k
}
6569
6570
0
fn ref_i31(
6571
0
    _u: &mut Unstructured,
6572
0
    _module: &Module,
6573
0
    builder: &mut CodeBuilder,
6574
0
    instructions: &mut Vec<Instruction>,
6575
0
) -> Result<()> {
6576
0
    builder.pop_operand();
6577
0
    builder.push_operand(Some(ValType::Ref(RefType {
6578
0
        nullable: false,
6579
0
        heap_type: HeapType::I31,
6580
0
    })));
6581
0
    instructions.push(Instruction::RefI31);
6582
0
    Ok(())
6583
0
}
6584
6585
#[inline]
6586
81.2k
fn i31_get_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6587
81.2k
    module.config.gc_enabled
6588
0
        && builder.type_on_stack(
6589
0
            module,
6590
0
            ValType::Ref(RefType {
6591
0
                nullable: true,
6592
0
                heap_type: HeapType::I31,
6593
0
            }),
6594
0
        )
6595
81.2k
}
6596
6597
0
fn i31_get(
6598
0
    u: &mut Unstructured,
6599
0
    _module: &Module,
6600
0
    builder: &mut CodeBuilder,
6601
0
    instructions: &mut Vec<Instruction>,
6602
0
) -> Result<()> {
6603
0
    builder.pop_operand();
6604
0
    builder.push_operand(Some(ValType::I32));
6605
0
    instructions.push(if u.arbitrary()? {
6606
0
        Instruction::I31GetS
6607
    } else {
6608
0
        Instruction::I31GetU
6609
    });
6610
0
    Ok(())
6611
0
}
6612
6613
#[inline]
6614
81.2k
fn any_convert_extern_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6615
81.2k
    module.config.gc_enabled
6616
0
        && builder.type_on_stack(
6617
0
            module,
6618
0
            ValType::Ref(RefType {
6619
0
                nullable: true,
6620
0
                heap_type: HeapType::Extern,
6621
0
            }),
6622
0
        )
6623
81.2k
}
6624
6625
0
fn any_convert_extern(
6626
0
    u: &mut Unstructured,
6627
0
    _module: &Module,
6628
0
    builder: &mut CodeBuilder,
6629
0
    instructions: &mut Vec<Instruction>,
6630
0
) -> Result<()> {
6631
0
    let nullable = match builder.pop_ref_type() {
6632
0
        None => u.arbitrary()?,
6633
0
        Some(r) => r.nullable,
6634
    };
6635
0
    builder.push_operand(Some(ValType::Ref(RefType {
6636
0
        nullable,
6637
0
        heap_type: HeapType::Any,
6638
0
    })));
6639
0
    instructions.push(Instruction::AnyConvertExtern);
6640
0
    Ok(())
6641
0
}
6642
6643
#[inline]
6644
81.2k
fn extern_convert_any_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6645
81.2k
    module.config.gc_enabled
6646
0
        && builder.type_on_stack(
6647
0
            module,
6648
0
            ValType::Ref(RefType {
6649
0
                nullable: true,
6650
0
                heap_type: HeapType::Any,
6651
0
            }),
6652
0
        )
6653
81.2k
}
6654
6655
0
fn extern_convert_any(
6656
0
    u: &mut Unstructured,
6657
0
    _module: &Module,
6658
0
    builder: &mut CodeBuilder,
6659
0
    instructions: &mut Vec<Instruction>,
6660
0
) -> Result<()> {
6661
0
    let nullable = match builder.pop_ref_type() {
6662
0
        None => u.arbitrary()?,
6663
0
        Some(r) => r.nullable,
6664
    };
6665
0
    builder.push_operand(Some(ValType::Ref(RefType {
6666
0
        nullable,
6667
0
        heap_type: HeapType::Extern,
6668
0
    })));
6669
0
    instructions.push(Instruction::ExternConvertAny);
6670
0
    Ok(())
6671
0
}
6672
6673
0
fn lane_index(u: &mut Unstructured, number_of_lanes: u8) -> Result<u8> {
6674
0
    u.int_in_range(0..=(number_of_lanes - 1))
6675
0
}
6676
6677
#[inline]
6678
5.36M
fn simd_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6679
5.36M
    !module.config.disallow_traps
6680
5.36M
        && module.config.simd_enabled
6681
0
        && builder.types_on_stack(module, &[ValType::V128])
6682
5.36M
}
6683
6684
#[inline]
6685
324k
fn simd_v128_on_stack_relaxed(module: &Module, builder: &mut CodeBuilder) -> bool {
6686
324k
    !module.config.disallow_traps
6687
324k
        && module.config.relaxed_simd_enabled
6688
0
        && builder.types_on_stack(module, &[ValType::V128])
6689
324k
}
6690
6691
#[inline]
6692
9.91M
fn simd_v128_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6693
9.91M
    !module.config.disallow_traps
6694
9.91M
        && module.config.simd_enabled
6695
0
        && builder.types_on_stack(module, &[ValType::V128, ValType::V128])
6696
9.91M
}
6697
6698
#[inline]
6699
568k
fn simd_v128_v128_on_stack_relaxed(module: &Module, builder: &mut CodeBuilder) -> bool {
6700
568k
    !module.config.disallow_traps
6701
568k
        && module.config.relaxed_simd_enabled
6702
0
        && builder.types_on_stack(module, &[ValType::V128, ValType::V128])
6703
568k
}
6704
6705
#[inline]
6706
81.2k
fn simd_v128_v128_v128_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6707
81.2k
    !module.config.disallow_traps
6708
81.2k
        && module.config.simd_enabled
6709
0
        && builder.types_on_stack(module, &[ValType::V128, ValType::V128, ValType::V128])
6710
81.2k
}
6711
6712
#[inline]
6713
731k
fn simd_v128_v128_v128_on_stack_relaxed(module: &Module, builder: &mut CodeBuilder) -> bool {
6714
731k
    !module.config.disallow_traps
6715
731k
        && module.config.relaxed_simd_enabled
6716
0
        && builder.types_on_stack(module, &[ValType::V128, ValType::V128, ValType::V128])
6717
731k
}
6718
6719
#[inline]
6720
1.21M
fn simd_v128_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6721
1.21M
    !module.config.disallow_traps
6722
1.21M
        && module.config.simd_enabled
6723
0
        && builder.types_on_stack(module, &[ValType::V128, ValType::I32])
6724
1.21M
}
6725
6726
#[inline]
6727
81.2k
fn simd_v128_i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6728
81.2k
    !module.config.disallow_traps
6729
81.2k
        && module.config.simd_enabled
6730
0
        && builder.types_on_stack(module, &[ValType::V128, ValType::I64])
6731
81.2k
}
6732
6733
#[inline]
6734
81.2k
fn simd_v128_f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6735
81.2k
    !module.config.disallow_traps
6736
81.2k
        && module.config.simd_enabled
6737
0
        && builder.types_on_stack(module, &[ValType::V128, ValType::F32])
6738
81.2k
}
6739
6740
#[inline]
6741
81.2k
fn simd_v128_f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6742
81.2k
    !module.config.disallow_traps
6743
81.2k
        && module.config.simd_enabled
6744
0
        && builder.types_on_stack(module, &[ValType::V128, ValType::F64])
6745
81.2k
}
6746
6747
#[inline]
6748
243k
fn simd_i32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6749
243k
    !module.config.disallow_traps
6750
243k
        && module.config.simd_enabled
6751
0
        && builder.type_on_stack(module, ValType::I32)
6752
243k
}
6753
6754
#[inline]
6755
81.2k
fn simd_i64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6756
81.2k
    !module.config.disallow_traps
6757
81.2k
        && module.config.simd_enabled
6758
0
        && builder.type_on_stack(module, ValType::I64)
6759
81.2k
}
6760
6761
#[inline]
6762
81.2k
fn simd_f32_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6763
81.2k
    !module.config.disallow_traps
6764
81.2k
        && module.config.simd_enabled
6765
0
        && builder.type_on_stack(module, ValType::F32)
6766
81.2k
}
6767
6768
#[inline]
6769
81.2k
fn simd_f64_on_stack(module: &Module, builder: &mut CodeBuilder) -> bool {
6770
81.2k
    !module.config.disallow_traps
6771
81.2k
        && module.config.simd_enabled
6772
0
        && builder.type_on_stack(module, ValType::F64)
6773
81.2k
}
6774
6775
#[inline]
6776
1.05M
fn simd_have_memory_and_offset(module: &Module, builder: &mut CodeBuilder) -> bool {
6777
1.05M
    !module.config.disallow_traps
6778
1.05M
        && module.config.simd_enabled
6779
0
        && have_memory_and_offset(module, builder)
6780
1.05M
}
6781
6782
#[inline]
6783
324k
fn simd_have_memory_and_offset_and_v128(module: &Module, builder: &mut CodeBuilder) -> bool {
6784
324k
    !module.config.disallow_traps
6785
324k
        && module.config.simd_enabled
6786
0
        && store_valid(module, builder, || ValType::V128)
6787
324k
}
6788
6789
#[inline]
6790
324k
fn simd_load_lane_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6791
324k
    // The SIMD non-trapping case is not yet implemented.
6792
324k
    !module.config.disallow_traps && simd_have_memory_and_offset_and_v128(module, builder)
6793
324k
}
6794
6795
#[inline]
6796
406k
fn simd_v128_store_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6797
406k
    !module.config.disallow_traps
6798
406k
        && module.config.simd_enabled
6799
0
        && store_valid(module, builder, || ValType::V128)
6800
406k
}
6801
6802
#[inline]
6803
324k
fn simd_store_lane_valid(module: &Module, builder: &mut CodeBuilder) -> bool {
6804
324k
    // The SIMD non-trapping case is not yet implemented.
6805
324k
    !module.config.disallow_traps && simd_v128_store_valid(module, builder)
6806
324k
}
6807
6808
#[inline]
6809
81.2k
fn simd_enabled(module: &Module, _: &mut CodeBuilder) -> bool {
6810
81.2k
    module.config.simd_enabled
6811
81.2k
}
6812
6813
macro_rules! simd_load {
6814
    ($instruction:ident, $generator_fn_name:ident, $alignments:expr) => {
6815
0
        fn $generator_fn_name(
6816
0
            u: &mut Unstructured,
6817
0
            module: &Module,
6818
0
            builder: &mut CodeBuilder,
6819
0
6820
0
            instructions: &mut Vec<Instruction>,
6821
0
        ) -> Result<()> {
6822
0
            let memarg = mem_arg(u, module, builder, $alignments)?;
6823
0
            builder.push_operands(&[ValType::V128]);
6824
0
            if module.config.disallow_traps {
6825
0
                no_traps::load(
6826
0
                    Instruction::$instruction(memarg),
6827
0
                    module,
6828
0
                    builder,
6829
0
                    instructions,
6830
0
                );
6831
0
            } else {
6832
0
                instructions.push(Instruction::$instruction(memarg));
6833
0
            }
6834
0
            Ok(())
6835
0
        }
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9v128_load
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13v128_load8x8s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13v128_load8x8u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14v128_load16x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14v128_load16x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14v128_load32x2s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14v128_load32x2u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder16v128_load8_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17v128_load16_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17v128_load32_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17v128_load64_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder16v128_load32_zero
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder16v128_load64_zero
6836
    };
6837
}
6838
6839
simd_load!(V128Load, v128_load, &[0, 1, 2, 3, 4]);
6840
simd_load!(V128Load8x8S, v128_load8x8s, &[0, 1, 2, 3]);
6841
simd_load!(V128Load8x8U, v128_load8x8u, &[0, 1, 2, 3]);
6842
simd_load!(V128Load16x4S, v128_load16x4s, &[0, 1, 2, 3]);
6843
simd_load!(V128Load16x4U, v128_load16x4u, &[0, 1, 2, 3]);
6844
simd_load!(V128Load32x2S, v128_load32x2s, &[0, 1, 2, 3]);
6845
simd_load!(V128Load32x2U, v128_load32x2u, &[0, 1, 2, 3]);
6846
simd_load!(V128Load8Splat, v128_load8_splat, &[0]);
6847
simd_load!(V128Load16Splat, v128_load16_splat, &[0, 1]);
6848
simd_load!(V128Load32Splat, v128_load32_splat, &[0, 1, 2]);
6849
simd_load!(V128Load64Splat, v128_load64_splat, &[0, 1, 2, 3]);
6850
simd_load!(V128Load32Zero, v128_load32_zero, &[0, 1, 2]);
6851
simd_load!(V128Load64Zero, v128_load64_zero, &[0, 1, 2, 3]);
6852
6853
0
fn v128_store(
6854
0
    u: &mut Unstructured,
6855
0
    module: &Module,
6856
0
    builder: &mut CodeBuilder,
6857
0
    instructions: &mut Vec<Instruction>,
6858
0
) -> Result<()> {
6859
0
    builder.pop_operands(module, &[ValType::V128]);
6860
0
    let memarg = mem_arg(u, module, builder, &[0, 1, 2, 3, 4])?;
6861
0
    if module.config.disallow_traps {
6862
0
        no_traps::store(
6863
0
            Instruction::V128Store(memarg),
6864
0
            module,
6865
0
            builder,
6866
0
            instructions,
6867
0
        );
6868
0
    } else {
6869
0
        instructions.push(Instruction::V128Store(memarg));
6870
0
    }
6871
0
    Ok(())
6872
0
}
6873
6874
macro_rules! simd_load_lane {
6875
    ($instruction:ident, $generator_fn_name:ident, $alignments:expr, $number_of_lanes:expr) => {
6876
0
        fn $generator_fn_name(
6877
0
            u: &mut Unstructured,
6878
0
            module: &Module,
6879
0
            builder: &mut CodeBuilder,
6880
0
            instructions: &mut Vec<Instruction>,
6881
0
        ) -> Result<()> {
6882
0
            builder.pop_operands(module, &[ValType::V128]);
6883
0
            let memarg = mem_arg(u, module, builder, $alignments)?;
6884
0
            builder.push_operands(&[ValType::V128]);
6885
0
            instructions.push(Instruction::$instruction {
6886
0
                memarg,
6887
0
                lane: lane_index(u, $number_of_lanes)?,
6888
            });
6889
0
            Ok(())
6890
0
        }
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15v128_load8_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder16v128_load16_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder16v128_load32_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder16v128_load64_lane
6891
    };
6892
}
6893
6894
simd_load_lane!(V128Load8Lane, v128_load8_lane, &[0], 16);
6895
simd_load_lane!(V128Load16Lane, v128_load16_lane, &[0, 1], 8);
6896
simd_load_lane!(V128Load32Lane, v128_load32_lane, &[0, 1, 2], 4);
6897
simd_load_lane!(V128Load64Lane, v128_load64_lane, &[0, 1, 2, 3], 2);
6898
6899
macro_rules! simd_store_lane {
6900
    ($instruction:ident, $generator_fn_name:ident, $alignments:expr, $number_of_lanes:expr) => {
6901
0
        fn $generator_fn_name(
6902
0
            u: &mut Unstructured,
6903
0
            module: &Module,
6904
0
            builder: &mut CodeBuilder,
6905
0
            instructions: &mut Vec<Instruction>,
6906
0
        ) -> Result<()> {
6907
0
            builder.pop_operands(module, &[ValType::V128]);
6908
0
            let memarg = mem_arg(u, module, builder, $alignments)?;
6909
0
            instructions.push(Instruction::$instruction {
6910
0
                memarg,
6911
0
                lane: lane_index(u, $number_of_lanes)?,
6912
            });
6913
0
            Ok(())
6914
0
        }
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder16v128_store8_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17v128_store16_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17v128_store32_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17v128_store64_lane
6915
    };
6916
}
6917
6918
simd_store_lane!(V128Store8Lane, v128_store8_lane, &[0], 16);
6919
simd_store_lane!(V128Store16Lane, v128_store16_lane, &[0, 1], 8);
6920
simd_store_lane!(V128Store32Lane, v128_store32_lane, &[0, 1, 2], 4);
6921
simd_store_lane!(V128Store64Lane, v128_store64_lane, &[0, 1, 2, 3], 2);
6922
6923
0
fn v128_const(
6924
0
    u: &mut Unstructured,
6925
0
    _module: &Module,
6926
0
    builder: &mut CodeBuilder,
6927
0
    instructions: &mut Vec<Instruction>,
6928
0
) -> Result<()> {
6929
0
    builder.push_operands(&[ValType::V128]);
6930
0
    let c = i128::from_le_bytes(u.arbitrary()?);
6931
0
    instructions.push(Instruction::V128Const(c));
6932
0
    Ok(())
6933
0
}
6934
6935
0
fn i8x16_shuffle(
6936
0
    u: &mut Unstructured,
6937
0
    module: &Module,
6938
0
    builder: &mut CodeBuilder,
6939
0
    instructions: &mut Vec<Instruction>,
6940
0
) -> Result<()> {
6941
0
    builder.pop_operands(module, &[ValType::V128, ValType::V128]);
6942
0
    builder.push_operands(&[ValType::V128]);
6943
0
    let mut lanes = [0; 16];
6944
0
    for i in 0..16 {
6945
0
        lanes[i] = u.int_in_range(0..=31)?;
6946
    }
6947
0
    instructions.push(Instruction::I8x16Shuffle(lanes));
6948
0
    Ok(())
6949
0
}
6950
6951
macro_rules! simd_lane_access {
6952
    ($instruction:ident, $generator_fn_name:ident, $in_types:expr => $out_types:expr, $number_of_lanes:expr) => {
6953
0
        fn $generator_fn_name(
6954
0
            u: &mut Unstructured,
6955
0
            module: &Module,
6956
0
            builder: &mut CodeBuilder,
6957
0
            instructions: &mut Vec<Instruction>,
6958
0
        ) -> Result<()> {
6959
0
            builder.pop_operands(module, $in_types);
6960
0
            builder.push_operands($out_types);
6961
0
            instructions.push(Instruction::$instruction(lane_index(u, $number_of_lanes)?));
6962
0
            Ok(())
6963
0
        }
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder20i8x16_extract_lane_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder20i8x16_extract_lane_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18i8x16_replace_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder20i16x8_extract_lane_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder20i16x8_extract_lane_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18i16x8_replace_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18i32x4_extract_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18i32x4_replace_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18i64x2_extract_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18i64x2_replace_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18f32x4_extract_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18f32x4_replace_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18f64x2_extract_lane
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18f64x2_replace_lane
6964
    };
6965
}
6966
6967
simd_lane_access!(I8x16ExtractLaneS, i8x16_extract_lane_s, &[ValType::V128] => &[ValType::I32], 16);
6968
simd_lane_access!(I8x16ExtractLaneU, i8x16_extract_lane_u, &[ValType::V128] => &[ValType::I32], 16);
6969
simd_lane_access!(I8x16ReplaceLane, i8x16_replace_lane, &[ValType::V128, ValType::I32] => &[ValType::V128], 16);
6970
simd_lane_access!(I16x8ExtractLaneS, i16x8_extract_lane_s, &[ValType::V128] => &[ValType::I32], 8);
6971
simd_lane_access!(I16x8ExtractLaneU, i16x8_extract_lane_u, &[ValType::V128] => &[ValType::I32], 8);
6972
simd_lane_access!(I16x8ReplaceLane, i16x8_replace_lane, &[ValType::V128, ValType::I32] => &[ValType::V128], 8);
6973
simd_lane_access!(I32x4ExtractLane, i32x4_extract_lane, &[ValType::V128] => &[ValType::I32], 4);
6974
simd_lane_access!(I32x4ReplaceLane, i32x4_replace_lane, &[ValType::V128, ValType::I32] => &[ValType::V128], 4);
6975
simd_lane_access!(I64x2ExtractLane, i64x2_extract_lane, &[ValType::V128] => &[ValType::I64], 2);
6976
simd_lane_access!(I64x2ReplaceLane, i64x2_replace_lane, &[ValType::V128, ValType::I64] => &[ValType::V128], 2);
6977
simd_lane_access!(F32x4ExtractLane, f32x4_extract_lane, &[ValType::V128] => &[ValType::F32], 4);
6978
simd_lane_access!(F32x4ReplaceLane, f32x4_replace_lane, &[ValType::V128, ValType::F32] => &[ValType::V128], 4);
6979
simd_lane_access!(F64x2ExtractLane, f64x2_extract_lane, &[ValType::V128] => &[ValType::F64], 2);
6980
simd_lane_access!(F64x2ReplaceLane, f64x2_replace_lane, &[ValType::V128, ValType::F64] => &[ValType::V128], 2);
6981
6982
macro_rules! simd_binop {
6983
    ($instruction:ident, $generator_fn_name:ident) => {
6984
0
        fn $generator_fn_name(
6985
0
            _: &mut Unstructured,
6986
0
            module: &Module,
6987
0
            builder: &mut CodeBuilder,
6988
0
6989
0
            instructions: &mut Vec<Instruction>,
6990
0
        ) -> Result<()> {
6991
0
            builder.pop_operands(module, &[ValType::V128, ValType::V128]);
6992
0
            builder.push_operands(&[ValType::V128]);
6993
0
            instructions.push(Instruction::$instruction);
6994
0
            Ok(())
6995
0
        }
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13i8x16_swizzle
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8i8x16_eq
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8i8x16_ne
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i8x16_lt_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i8x16_lt_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i8x16_gt_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i8x16_gt_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i8x16_le_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i8x16_le_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i8x16_ge_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i8x16_ge_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8i16x8_eq
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8i16x8_ne
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i16x8_lt_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i16x8_lt_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i16x8_gt_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i16x8_gt_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i16x8_le_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i16x8_le_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i16x8_ge_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i16x8_ge_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8i32x4_eq
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8i32x4_ne
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i32x4_lt_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i32x4_lt_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i32x4_gt_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i32x4_gt_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i32x4_le_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i32x4_le_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i32x4_ge_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i32x4_ge_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8i64x2_eq
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8i64x2_ne
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i64x2_lt_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i64x2_gt_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i64x2_le_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10i64x2_ge_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f32x4_eq
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f32x4_ne
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f32x4_lt
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f32x4_gt
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f32x4_le
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f32x4_ge
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f64x2_eq
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f64x2_ne
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f64x2_lt
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f64x2_gt
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f64x2_le
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8f64x2_ge
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8v128_and
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder12v128_and_not
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder7v128_or
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8v128_xor
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder19i8x16_narrow_i16x8s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder19i8x16_narrow_i16x8u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i8x16_add
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15i8x16_add_sat_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15i8x16_add_sat_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i8x16_sub
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15i8x16_sub_sat_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15i8x16_sub_sat_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i8x16_min_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i8x16_min_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i8x16_max_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i8x16_max_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder12i8x16_avgr_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder19i16x8q15_mulr_sat_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder19i16x8_narrow_i32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder19i16x8_narrow_i32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i16x8_add
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15i16x8_add_sat_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15i16x8_add_sat_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i16x8_sub
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15i16x8_sub_sat_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder15i16x8_sub_sat_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i16x8_mul
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i16x8_min_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i16x8_min_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i16x8_max_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i16x8_max_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder12i16x8_avgr_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i16x8_extmul_low_i8x16s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i16x8_extmul_high_i8x16s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i16x8_extmul_low_i8x16u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i16x8_extmul_high_i8x16u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i32x4_add
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i32x4_sub
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i32x4_mul
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i32x4_min_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i32x4_min_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i32x4_max_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i32x4_max_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder16i32x4_dot_i16x8s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i32x4_extmul_low_i16x8s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i32x4_extmul_high_i16x8s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i32x4_extmul_low_i16x8u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i32x4_extmul_high_i16x8u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i64x2_add
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i64x2_sub
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i64x2_mul
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i64x2_extmul_low_i32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i64x2_extmul_high_i32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i64x2_extmul_low_i32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i64x2_extmul_high_i32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f32x4_add
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f32x4_sub
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f32x4_mul
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f32x4_div
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f32x4_min
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f32x4_max
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10f32x4p_min
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10f32x4p_max
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f64x2_add
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f64x2_sub
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f64x2_mul
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f64x2_div
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f64x2_min
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f64x2_max
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10f64x2p_min
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10f64x2p_max
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder21i8x16_relaxed_swizzle
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17f32x4_relaxed_min
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17f32x4_relaxed_max
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17f64x2_relaxed_min
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder17f64x2_relaxed_max
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i16x8_relaxed_q15mulr_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder31i16x8_relaxed_dot_i8x16_i7x16_s
6996
    };
6997
}
6998
6999
macro_rules! simd_unop {
7000
    ($instruction:ident, $generator_fn_name:ident) => {
7001
        simd_unop!($instruction, $generator_fn_name, V128 -> V128);
7002
    };
7003
7004
    ($instruction:ident, $generator_fn_name:ident, $in_type:ident -> $out_type:ident) => {
7005
0
        fn $generator_fn_name(
7006
0
            _: &mut Unstructured,
7007
0
            module: &Module,
7008
0
            builder: &mut CodeBuilder,
7009
0
7010
0
       instructions: &mut Vec<Instruction>, ) -> Result<()> {
7011
0
            builder.pop_operands(module, &[ValType::$in_type]);
7012
0
            builder.push_operands(&[ValType::$out_type]);
7013
0
            instructions.push(Instruction::$instruction);
7014
0
            Ok(())
7015
0
        }
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i8x16_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i16x8_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i32x4_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i64x2_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11f32x4_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11f64x2_splat
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder8v128_not
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13v128_any_true
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i8x16_abs
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i8x16_neg
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder12i8x16_popcnt
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14i8x16_all_true
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13i8x16_bitmask
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder28i16x8_extadd_pairwise_i8x16s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder28i16x8_extadd_pairwise_i8x16u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i16x8_abs
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i16x8_neg
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14i16x8_all_true
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13i16x8_bitmask
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i16x8_extend_low_i8x16s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i16x8_extend_high_i8x16s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i16x8_extend_low_i8x16u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i16x8_extend_high_i8x16u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder28i32x4_extadd_pairwise_i16x8s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder28i32x4_extadd_pairwise_i16x8u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i32x4_abs
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i32x4_neg
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14i32x4_all_true
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13i32x4_bitmask
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i32x4_extend_low_i16x8s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i32x4_extend_high_i16x8s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i32x4_extend_low_i16x8u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i32x4_extend_high_i16x8u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i64x2_abs
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i64x2_neg
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14i64x2_all_true
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13i64x2_bitmask
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i64x2_extend_low_i32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i64x2_extend_high_i32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23i64x2_extend_low_i32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i64x2_extend_high_i32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10f32x4_ceil
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11f32x4_floor
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11f32x4_trunc
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13f32x4_nearest
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f32x4_abs
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f32x4_neg
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10f32x4_sqrt
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10f64x2_ceil
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11f64x2_floor
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11f64x2_trunc
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder13f64x2_nearest
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f64x2_abs
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9f64x2_neg
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder10f64x2_sqrt
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder22i32x4_trunc_sat_f32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder22i32x4_trunc_sat_f32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder20f32x4_convert_i32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder20f32x4_convert_i32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder27i32x4_trunc_sat_f64x2s_zero
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder27i32x4_trunc_sat_f64x2u_zero
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24f64x2_convert_low_i32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24f64x2_convert_low_i32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23f32x4_demote_f64x2_zero
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder23f64x2_promote_low_f32x4
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder26i32x4_relaxed_trunc_f32x4s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder26i32x4_relaxed_trunc_f32x4u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder31i32x4_relaxed_trunc_f64x2s_zero
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder31i32x4_relaxed_trunc_f64x2u_zero
7016
    };
7017
}
7018
7019
macro_rules! simd_ternop {
7020
    ($instruction:ident, $generator_fn_name:ident) => {
7021
0
        fn $generator_fn_name(
7022
0
            _: &mut Unstructured,
7023
0
            module: &Module,
7024
0
            builder: &mut CodeBuilder,
7025
0
7026
0
            instructions: &mut Vec<Instruction>,
7027
0
        ) -> Result<()> {
7028
0
            builder.pop_operands(module, &[ValType::V128, ValType::V128, ValType::V128]);
7029
0
            builder.push_operands(&[ValType::V128]);
7030
0
            instructions.push(Instruction::$instruction);
7031
0
            Ok(())
7032
0
        }
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder14v128_bitselect
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18f32x4_relaxed_madd
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder19f32x4_relaxed_nmadd
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder18f64x2_relaxed_madd
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder19f64x2_relaxed_nmadd
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i8x16_relaxed_laneselect
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i16x8_relaxed_laneselect
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i32x4_relaxed_laneselect
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder24i64x2_relaxed_laneselect
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder35i32x4_relaxed_dot_i8x16_i7x16_add_s
7033
    };
7034
}
7035
7036
macro_rules! simd_shift {
7037
    ($instruction:ident, $generator_fn_name:ident) => {
7038
0
        fn $generator_fn_name(
7039
0
            _: &mut Unstructured,
7040
0
            module: &Module,
7041
0
            builder: &mut CodeBuilder,
7042
0
7043
0
            instructions: &mut Vec<Instruction>,
7044
0
        ) -> Result<()> {
7045
0
            builder.pop_operands(module, &[ValType::V128, ValType::I32]);
7046
0
            builder.push_operands(&[ValType::V128]);
7047
0
            instructions.push(Instruction::$instruction);
7048
0
            Ok(())
7049
0
        }
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i8x16_shl
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i8x16_shr_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i8x16_shr_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i16x8_shl
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i16x8_shr_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i16x8_shr_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i32x4_shl
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i32x4_shr_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i32x4_shr_u
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder9i64x2_shl
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i64x2_shr_s
Unexecuted instantiation: _RNvNtNtCs4eJdYXiOSk9_10wasm_smith4core12code_builder11i64x2_shr_u
7050
    };
7051
}
7052
7053
simd_unop!(I8x16Splat, i8x16_splat, I32 -> V128);
7054
simd_unop!(I16x8Splat, i16x8_splat, I32 -> V128);
7055
simd_unop!(I32x4Splat, i32x4_splat, I32 -> V128);
7056
simd_unop!(I64x2Splat, i64x2_splat, I64 -> V128);
7057
simd_unop!(F32x4Splat, f32x4_splat, F32 -> V128);
7058
simd_unop!(F64x2Splat, f64x2_splat, F64 -> V128);
7059
simd_binop!(I8x16Swizzle, i8x16_swizzle);
7060
simd_binop!(I8x16Eq, i8x16_eq);
7061
simd_binop!(I8x16Ne, i8x16_ne);
7062
simd_binop!(I8x16LtS, i8x16_lt_s);
7063
simd_binop!(I8x16LtU, i8x16_lt_u);
7064
simd_binop!(I8x16GtS, i8x16_gt_s);
7065
simd_binop!(I8x16GtU, i8x16_gt_u);
7066
simd_binop!(I8x16LeS, i8x16_le_s);
7067
simd_binop!(I8x16LeU, i8x16_le_u);
7068
simd_binop!(I8x16GeS, i8x16_ge_s);
7069
simd_binop!(I8x16GeU, i8x16_ge_u);
7070
simd_binop!(I16x8Eq, i16x8_eq);
7071
simd_binop!(I16x8Ne, i16x8_ne);
7072
simd_binop!(I16x8LtS, i16x8_lt_s);
7073
simd_binop!(I16x8LtU, i16x8_lt_u);
7074
simd_binop!(I16x8GtS, i16x8_gt_s);
7075
simd_binop!(I16x8GtU, i16x8_gt_u);
7076
simd_binop!(I16x8LeS, i16x8_le_s);
7077
simd_binop!(I16x8LeU, i16x8_le_u);
7078
simd_binop!(I16x8GeS, i16x8_ge_s);
7079
simd_binop!(I16x8GeU, i16x8_ge_u);
7080
simd_binop!(I32x4Eq, i32x4_eq);
7081
simd_binop!(I32x4Ne, i32x4_ne);
7082
simd_binop!(I32x4LtS, i32x4_lt_s);
7083
simd_binop!(I32x4LtU, i32x4_lt_u);
7084
simd_binop!(I32x4GtS, i32x4_gt_s);
7085
simd_binop!(I32x4GtU, i32x4_gt_u);
7086
simd_binop!(I32x4LeS, i32x4_le_s);
7087
simd_binop!(I32x4LeU, i32x4_le_u);
7088
simd_binop!(I32x4GeS, i32x4_ge_s);
7089
simd_binop!(I32x4GeU, i32x4_ge_u);
7090
simd_binop!(I64x2Eq, i64x2_eq);
7091
simd_binop!(I64x2Ne, i64x2_ne);
7092
simd_binop!(I64x2LtS, i64x2_lt_s);
7093
simd_binop!(I64x2GtS, i64x2_gt_s);
7094
simd_binop!(I64x2LeS, i64x2_le_s);
7095
simd_binop!(I64x2GeS, i64x2_ge_s);
7096
simd_binop!(F32x4Eq, f32x4_eq);
7097
simd_binop!(F32x4Ne, f32x4_ne);
7098
simd_binop!(F32x4Lt, f32x4_lt);
7099
simd_binop!(F32x4Gt, f32x4_gt);
7100
simd_binop!(F32x4Le, f32x4_le);
7101
simd_binop!(F32x4Ge, f32x4_ge);
7102
simd_binop!(F64x2Eq, f64x2_eq);
7103
simd_binop!(F64x2Ne, f64x2_ne);
7104
simd_binop!(F64x2Lt, f64x2_lt);
7105
simd_binop!(F64x2Gt, f64x2_gt);
7106
simd_binop!(F64x2Le, f64x2_le);
7107
simd_binop!(F64x2Ge, f64x2_ge);
7108
simd_unop!(V128Not, v128_not);
7109
simd_binop!(V128And, v128_and);
7110
simd_binop!(V128AndNot, v128_and_not);
7111
simd_binop!(V128Or, v128_or);
7112
simd_binop!(V128Xor, v128_xor);
7113
simd_unop!(V128AnyTrue, v128_any_true, V128 -> I32);
7114
simd_unop!(I8x16Abs, i8x16_abs);
7115
simd_unop!(I8x16Neg, i8x16_neg);
7116
simd_unop!(I8x16Popcnt, i8x16_popcnt);
7117
simd_unop!(I8x16AllTrue, i8x16_all_true, V128 -> I32);
7118
simd_unop!(I8x16Bitmask, i8x16_bitmask, V128 -> I32);
7119
simd_binop!(I8x16NarrowI16x8S, i8x16_narrow_i16x8s);
7120
simd_binop!(I8x16NarrowI16x8U, i8x16_narrow_i16x8u);
7121
simd_shift!(I8x16Shl, i8x16_shl);
7122
simd_shift!(I8x16ShrS, i8x16_shr_s);
7123
simd_shift!(I8x16ShrU, i8x16_shr_u);
7124
simd_binop!(I8x16Add, i8x16_add);
7125
simd_binop!(I8x16AddSatS, i8x16_add_sat_s);
7126
simd_binop!(I8x16AddSatU, i8x16_add_sat_u);
7127
simd_binop!(I8x16Sub, i8x16_sub);
7128
simd_binop!(I8x16SubSatS, i8x16_sub_sat_s);
7129
simd_binop!(I8x16SubSatU, i8x16_sub_sat_u);
7130
simd_binop!(I8x16MinS, i8x16_min_s);
7131
simd_binop!(I8x16MinU, i8x16_min_u);
7132
simd_binop!(I8x16MaxS, i8x16_max_s);
7133
simd_binop!(I8x16MaxU, i8x16_max_u);
7134
simd_binop!(I8x16AvgrU, i8x16_avgr_u);
7135
simd_unop!(I16x8ExtAddPairwiseI8x16S, i16x8_extadd_pairwise_i8x16s);
7136
simd_unop!(I16x8ExtAddPairwiseI8x16U, i16x8_extadd_pairwise_i8x16u);
7137
simd_unop!(I16x8Abs, i16x8_abs);
7138
simd_unop!(I16x8Neg, i16x8_neg);
7139
simd_binop!(I16x8Q15MulrSatS, i16x8q15_mulr_sat_s);
7140
simd_unop!(I16x8AllTrue, i16x8_all_true, V128 -> I32);
7141
simd_unop!(I16x8Bitmask, i16x8_bitmask, V128 -> I32);
7142
simd_binop!(I16x8NarrowI32x4S, i16x8_narrow_i32x4s);
7143
simd_binop!(I16x8NarrowI32x4U, i16x8_narrow_i32x4u);
7144
simd_unop!(I16x8ExtendLowI8x16S, i16x8_extend_low_i8x16s);
7145
simd_unop!(I16x8ExtendHighI8x16S, i16x8_extend_high_i8x16s);
7146
simd_unop!(I16x8ExtendLowI8x16U, i16x8_extend_low_i8x16u);
7147
simd_unop!(I16x8ExtendHighI8x16U, i16x8_extend_high_i8x16u);
7148
simd_shift!(I16x8Shl, i16x8_shl);
7149
simd_shift!(I16x8ShrS, i16x8_shr_s);
7150
simd_shift!(I16x8ShrU, i16x8_shr_u);
7151
simd_binop!(I16x8Add, i16x8_add);
7152
simd_binop!(I16x8AddSatS, i16x8_add_sat_s);
7153
simd_binop!(I16x8AddSatU, i16x8_add_sat_u);
7154
simd_binop!(I16x8Sub, i16x8_sub);
7155
simd_binop!(I16x8SubSatS, i16x8_sub_sat_s);
7156
simd_binop!(I16x8SubSatU, i16x8_sub_sat_u);
7157
simd_binop!(I16x8Mul, i16x8_mul);
7158
simd_binop!(I16x8MinS, i16x8_min_s);
7159
simd_binop!(I16x8MinU, i16x8_min_u);
7160
simd_binop!(I16x8MaxS, i16x8_max_s);
7161
simd_binop!(I16x8MaxU, i16x8_max_u);
7162
simd_binop!(I16x8AvgrU, i16x8_avgr_u);
7163
simd_binop!(I16x8ExtMulLowI8x16S, i16x8_extmul_low_i8x16s);
7164
simd_binop!(I16x8ExtMulHighI8x16S, i16x8_extmul_high_i8x16s);
7165
simd_binop!(I16x8ExtMulLowI8x16U, i16x8_extmul_low_i8x16u);
7166
simd_binop!(I16x8ExtMulHighI8x16U, i16x8_extmul_high_i8x16u);
7167
simd_unop!(I32x4ExtAddPairwiseI16x8S, i32x4_extadd_pairwise_i16x8s);
7168
simd_unop!(I32x4ExtAddPairwiseI16x8U, i32x4_extadd_pairwise_i16x8u);
7169
simd_unop!(I32x4Abs, i32x4_abs);
7170
simd_unop!(I32x4Neg, i32x4_neg);
7171
simd_unop!(I32x4AllTrue, i32x4_all_true, V128 -> I32);
7172
simd_unop!(I32x4Bitmask, i32x4_bitmask, V128 -> I32);
7173
simd_unop!(I32x4ExtendLowI16x8S, i32x4_extend_low_i16x8s);
7174
simd_unop!(I32x4ExtendHighI16x8S, i32x4_extend_high_i16x8s);
7175
simd_unop!(I32x4ExtendLowI16x8U, i32x4_extend_low_i16x8u);
7176
simd_unop!(I32x4ExtendHighI16x8U, i32x4_extend_high_i16x8u);
7177
simd_shift!(I32x4Shl, i32x4_shl);
7178
simd_shift!(I32x4ShrS, i32x4_shr_s);
7179
simd_shift!(I32x4ShrU, i32x4_shr_u);
7180
simd_binop!(I32x4Add, i32x4_add);
7181
simd_binop!(I32x4Sub, i32x4_sub);
7182
simd_binop!(I32x4Mul, i32x4_mul);
7183
simd_binop!(I32x4MinS, i32x4_min_s);
7184
simd_binop!(I32x4MinU, i32x4_min_u);
7185
simd_binop!(I32x4MaxS, i32x4_max_s);
7186
simd_binop!(I32x4MaxU, i32x4_max_u);
7187
simd_binop!(I32x4DotI16x8S, i32x4_dot_i16x8s);
7188
simd_binop!(I32x4ExtMulLowI16x8S, i32x4_extmul_low_i16x8s);
7189
simd_binop!(I32x4ExtMulHighI16x8S, i32x4_extmul_high_i16x8s);
7190
simd_binop!(I32x4ExtMulLowI16x8U, i32x4_extmul_low_i16x8u);
7191
simd_binop!(I32x4ExtMulHighI16x8U, i32x4_extmul_high_i16x8u);
7192
simd_unop!(I64x2Abs, i64x2_abs);
7193
simd_unop!(I64x2Neg, i64x2_neg);
7194
simd_unop!(I64x2AllTrue, i64x2_all_true, V128 -> I32);
7195
simd_unop!(I64x2Bitmask, i64x2_bitmask, V128 -> I32);
7196
simd_unop!(I64x2ExtendLowI32x4S, i64x2_extend_low_i32x4s);
7197
simd_unop!(I64x2ExtendHighI32x4S, i64x2_extend_high_i32x4s);
7198
simd_unop!(I64x2ExtendLowI32x4U, i64x2_extend_low_i32x4u);
7199
simd_unop!(I64x2ExtendHighI32x4U, i64x2_extend_high_i32x4u);
7200
simd_shift!(I64x2Shl, i64x2_shl);
7201
simd_shift!(I64x2ShrS, i64x2_shr_s);
7202
simd_shift!(I64x2ShrU, i64x2_shr_u);
7203
simd_binop!(I64x2Add, i64x2_add);
7204
simd_binop!(I64x2Sub, i64x2_sub);
7205
simd_binop!(I64x2Mul, i64x2_mul);
7206
simd_binop!(I64x2ExtMulLowI32x4S, i64x2_extmul_low_i32x4s);
7207
simd_binop!(I64x2ExtMulHighI32x4S, i64x2_extmul_high_i32x4s);
7208
simd_binop!(I64x2ExtMulLowI32x4U, i64x2_extmul_low_i32x4u);
7209
simd_binop!(I64x2ExtMulHighI32x4U, i64x2_extmul_high_i32x4u);
7210
simd_unop!(F32x4Ceil, f32x4_ceil);
7211
simd_unop!(F32x4Floor, f32x4_floor);
7212
simd_unop!(F32x4Trunc, f32x4_trunc);
7213
simd_unop!(F32x4Nearest, f32x4_nearest);
7214
simd_unop!(F32x4Abs, f32x4_abs);
7215
simd_unop!(F32x4Neg, f32x4_neg);
7216
simd_unop!(F32x4Sqrt, f32x4_sqrt);
7217
simd_binop!(F32x4Add, f32x4_add);
7218
simd_binop!(F32x4Sub, f32x4_sub);
7219
simd_binop!(F32x4Mul, f32x4_mul);
7220
simd_binop!(F32x4Div, f32x4_div);
7221
simd_binop!(F32x4Min, f32x4_min);
7222
simd_binop!(F32x4Max, f32x4_max);
7223
simd_binop!(F32x4PMin, f32x4p_min);
7224
simd_binop!(F32x4PMax, f32x4p_max);
7225
simd_unop!(F64x2Ceil, f64x2_ceil);
7226
simd_unop!(F64x2Floor, f64x2_floor);
7227
simd_unop!(F64x2Trunc, f64x2_trunc);
7228
simd_unop!(F64x2Nearest, f64x2_nearest);
7229
simd_unop!(F64x2Abs, f64x2_abs);
7230
simd_unop!(F64x2Neg, f64x2_neg);
7231
simd_unop!(F64x2Sqrt, f64x2_sqrt);
7232
simd_binop!(F64x2Add, f64x2_add);
7233
simd_binop!(F64x2Sub, f64x2_sub);
7234
simd_binop!(F64x2Mul, f64x2_mul);
7235
simd_binop!(F64x2Div, f64x2_div);
7236
simd_binop!(F64x2Min, f64x2_min);
7237
simd_binop!(F64x2Max, f64x2_max);
7238
simd_binop!(F64x2PMin, f64x2p_min);
7239
simd_binop!(F64x2PMax, f64x2p_max);
7240
simd_unop!(I32x4TruncSatF32x4S, i32x4_trunc_sat_f32x4s);
7241
simd_unop!(I32x4TruncSatF32x4U, i32x4_trunc_sat_f32x4u);
7242
simd_unop!(F32x4ConvertI32x4S, f32x4_convert_i32x4s);
7243
simd_unop!(F32x4ConvertI32x4U, f32x4_convert_i32x4u);
7244
simd_unop!(I32x4TruncSatF64x2SZero, i32x4_trunc_sat_f64x2s_zero);
7245
simd_unop!(I32x4TruncSatF64x2UZero, i32x4_trunc_sat_f64x2u_zero);
7246
simd_unop!(F64x2ConvertLowI32x4S, f64x2_convert_low_i32x4s);
7247
simd_unop!(F64x2ConvertLowI32x4U, f64x2_convert_low_i32x4u);
7248
simd_unop!(F32x4DemoteF64x2Zero, f32x4_demote_f64x2_zero);
7249
simd_unop!(F64x2PromoteLowF32x4, f64x2_promote_low_f32x4);
7250
simd_ternop!(V128Bitselect, v128_bitselect);
7251
simd_binop!(I8x16RelaxedSwizzle, i8x16_relaxed_swizzle);
7252
simd_unop!(I32x4RelaxedTruncF32x4S, i32x4_relaxed_trunc_f32x4s);
7253
simd_unop!(I32x4RelaxedTruncF32x4U, i32x4_relaxed_trunc_f32x4u);
7254
simd_unop!(I32x4RelaxedTruncF64x2SZero, i32x4_relaxed_trunc_f64x2s_zero);
7255
simd_unop!(I32x4RelaxedTruncF64x2UZero, i32x4_relaxed_trunc_f64x2u_zero);
7256
simd_ternop!(F32x4RelaxedMadd, f32x4_relaxed_madd);
7257
simd_ternop!(F32x4RelaxedNmadd, f32x4_relaxed_nmadd);
7258
simd_ternop!(F64x2RelaxedMadd, f64x2_relaxed_madd);
7259
simd_ternop!(F64x2RelaxedNmadd, f64x2_relaxed_nmadd);
7260
simd_ternop!(I8x16RelaxedLaneselect, i8x16_relaxed_laneselect);
7261
simd_ternop!(I16x8RelaxedLaneselect, i16x8_relaxed_laneselect);
7262
simd_ternop!(I32x4RelaxedLaneselect, i32x4_relaxed_laneselect);
7263
simd_ternop!(I64x2RelaxedLaneselect, i64x2_relaxed_laneselect);
7264
simd_binop!(F32x4RelaxedMin, f32x4_relaxed_min);
7265
simd_binop!(F32x4RelaxedMax, f32x4_relaxed_max);
7266
simd_binop!(F64x2RelaxedMin, f64x2_relaxed_min);
7267
simd_binop!(F64x2RelaxedMax, f64x2_relaxed_max);
7268
simd_binop!(I16x8RelaxedQ15mulrS, i16x8_relaxed_q15mulr_s);
7269
simd_binop!(I16x8RelaxedDotI8x16I7x16S, i16x8_relaxed_dot_i8x16_i7x16_s);
7270
simd_ternop!(
7271
    I32x4RelaxedDotI8x16I7x16AddS,
7272
    i32x4_relaxed_dot_i8x16_i7x16_add_s
7273
);
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/core/code_builder/no_traps.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::core::*;
2
use wasm_encoder::Instruction;
3
4
use super::CodeBuilder;
5
6
// For loads, we dynamically check whether the load will
7
// trap, and if it will then we generate a dummy value to
8
// use instead.
9
0
pub(crate) fn load<'a>(
10
0
    inst: Instruction<'a>,
11
0
    module: &Module,
12
0
    builder: &mut CodeBuilder,
13
0
    insts: &mut Vec<Instruction<'a>>,
14
0
) {
15
0
    let memarg = get_memarg(&inst);
16
0
    let memory = &module.memories[memarg.memory_index as usize];
17
0
    let address_type = if memory.memory64 {
18
0
        ValType::I64
19
    } else {
20
0
        ValType::I32
21
    };
22
    // Add a temporary local to hold this load's address.
23
0
    let address_local = builder.alloc_local(address_type);
24
0
25
0
    // Add a temporary local to hold the result of this load.
26
0
    let load_type = type_of_memory_access(&inst);
27
0
    let result_local = builder.alloc_local(load_type);
28
0
29
0
    // [address:address_type]
30
0
    insts.push(Instruction::LocalSet(address_local));
31
0
    // []
32
0
    insts.push(Instruction::Block(wasm_encoder::BlockType::Empty));
33
0
    {
34
0
        // []
35
0
        insts.push(Instruction::Block(wasm_encoder::BlockType::Empty));
36
0
        {
37
0
            // []
38
0
            insts.push(Instruction::MemorySize(memarg.memory_index));
39
0
            // [mem_size_in_pages:address_type]
40
0
            insts.push(int_const_inst(
41
0
                address_type,
42
0
                crate::page_size(memory).into(),
43
0
            ));
44
0
            // [mem_size_in_pages:address_type wasm_page_size:address_type]
45
0
            insts.push(int_mul_inst(address_type));
46
0
            // [mem_size_in_bytes:address_type]
47
0
            insts.push(int_const_inst(
48
0
                address_type,
49
0
                (memarg.offset + size_of_type_in_memory(load_type)) as i64,
50
0
            ));
51
0
            // [mem_size_in_bytes:address_type offset_and_size:address_type]
52
0
            insts.push(Instruction::LocalGet(address_local));
53
0
            // [mem_size_in_bytes:address_type offset_and_size:address_type address:address_type]
54
0
            insts.push(int_add_inst(address_type));
55
0
            // [mem_size_in_bytes:address_type highest_byte_accessed:address_type]
56
0
            insts.push(int_le_u_inst(address_type));
57
0
            // [load_will_trap:i32]
58
0
            insts.push(Instruction::BrIf(0));
59
0
            // []
60
0
            insts.push(Instruction::LocalGet(address_local));
61
0
            // [address:address_type]
62
0
            insts.push(int_const_inst(address_type, 0));
63
0
            // [address:address_type 0:address_type]
64
0
            insts.push(int_le_s_inst(address_type));
65
0
            // [load_will_trap:i32]
66
0
            insts.push(Instruction::BrIf(0));
67
0
            // []
68
0
            insts.push(Instruction::LocalGet(address_local));
69
0
            // [address:address_type]
70
0
            insts.push(inst);
71
0
            // [result:load_type]
72
0
            insts.push(Instruction::LocalSet(result_local));
73
0
            // []
74
0
            insts.push(Instruction::Br(1));
75
0
            // <unreachable>
76
0
        }
77
0
        // []
78
0
        insts.push(Instruction::End);
79
0
        // []
80
0
        insts.push(dummy_value_inst(load_type));
81
0
        // [dummy_value:load_type]
82
0
        insts.push(Instruction::LocalSet(result_local));
83
0
        // []
84
0
    }
85
0
    // []
86
0
    insts.push(Instruction::End);
87
0
    // []
88
0
    insts.push(Instruction::LocalGet(result_local));
89
0
    // [result:load_type]
90
0
}
91
92
// Stores are similar to loads: we check whether the store
93
// will trap, and if it will then we just drop the value.
94
0
pub(crate) fn store<'a>(
95
0
    inst: Instruction<'a>,
96
0
    module: &Module,
97
0
    builder: &mut CodeBuilder,
98
0
    insts: &mut Vec<Instruction<'a>>,
99
0
) {
100
0
    let memarg = get_memarg(&inst);
101
0
    let memory = &module.memories[memarg.memory_index as usize];
102
0
    let address_type = if memory.memory64 {
103
0
        ValType::I64
104
    } else {
105
0
        ValType::I32
106
    };
107
108
    // Add a temporary local to hold this store's address.
109
0
    let address_local = builder.alloc_local(address_type);
110
0
111
0
    // Add a temporary local to hold the value to store.
112
0
    let store_type = type_of_memory_access(&inst);
113
0
    let value_local = builder.alloc_local(store_type);
114
0
115
0
    // [address:address_type value:store_type]
116
0
    insts.push(Instruction::LocalSet(value_local));
117
0
    // [address:address_type]
118
0
    insts.push(Instruction::LocalSet(address_local));
119
0
    // []
120
0
    insts.push(Instruction::MemorySize(memarg.memory_index));
121
0
    // [mem_size_in_pages:address_type]
122
0
    insts.push(int_const_inst(
123
0
        address_type,
124
0
        crate::page_size(memory).into(),
125
0
    ));
126
0
    // [mem_size_in_pages:address_type wasm_page_size:address_type]
127
0
    insts.push(int_mul_inst(address_type));
128
0
    // [mem_size_in_bytes:address_type]
129
0
    insts.push(int_const_inst(
130
0
        address_type,
131
0
        (memarg.offset + size_of_type_in_memory(store_type)) as i64,
132
0
    ));
133
0
    // [mem_size_in_bytes:address_type offset_and_size:address_type]
134
0
    insts.push(Instruction::LocalGet(address_local));
135
0
    // [mem_size_in_bytes:address_type offset_and_size:address_type address:address_type]
136
0
    insts.push(int_add_inst(address_type));
137
0
    // [mem_size_in_bytes:address_type highest_byte_accessed:address_type]
138
0
    insts.push(int_le_u_inst(address_type));
139
0
    // [store_will_trap:i32]
140
0
    insts.push(Instruction::If(BlockType::Empty));
141
0
    insts.push(Instruction::Else);
142
0
    {
143
0
        // []
144
0
        insts.push(Instruction::LocalGet(address_local));
145
0
        // [address:address_type]
146
0
        insts.push(int_const_inst(address_type, 0));
147
0
        // [address:address_type 0:address_type]
148
0
        insts.push(int_le_s_inst(address_type));
149
0
        // [load_will_trap:i32]
150
0
        insts.push(Instruction::If(BlockType::Empty));
151
0
        insts.push(Instruction::Else);
152
0
        {
153
0
            // []
154
0
            insts.push(Instruction::LocalGet(address_local));
155
0
            // [address:address_type]
156
0
            insts.push(Instruction::LocalGet(value_local));
157
0
            // [address:address_type value:store_type]
158
0
            insts.push(inst);
159
0
            // []
160
0
        }
161
0
        insts.push(Instruction::End);
162
0
    }
163
0
    // []
164
0
    insts.push(Instruction::End);
165
0
}
166
167
// Unsigned integer division and remainder will trap when
168
// the divisor is 0. To avoid the trap, we will set any 0
169
// divisors to 1 prior to the operation.
170
//
171
// The code below is equivalent to this expression:
172
//
173
//     local.set $temp_divisor
174
//     (select (i32.eqz (local.get $temp_divisor) (i32.const 1) (local.get $temp_divisor))
175
0
pub(crate) fn unsigned_div_rem<'a>(
176
0
    inst: Instruction<'a>,
177
0
    builder: &mut CodeBuilder,
178
0
    insts: &mut Vec<Instruction<'a>>,
179
0
) {
180
0
    let op_type = type_of_integer_operation(&inst);
181
0
    let temp_divisor = builder.alloc_local(op_type);
182
0
183
0
    // [dividend:op_type divisor:op_type]
184
0
    insts.push(Instruction::LocalSet(temp_divisor));
185
0
    // [dividend:op_type]
186
0
    insts.push(int_const_inst(op_type, 1));
187
0
    // [dividend:op_type 1:op_type]
188
0
    insts.push(Instruction::LocalGet(temp_divisor));
189
0
    // [dividend:op_type 1:op_type divisor:op_type]
190
0
    insts.push(Instruction::LocalGet(temp_divisor));
191
0
    // [dividend:op_type 1:op_type divisor:op_type divisor:op_type]
192
0
    insts.push(eqz_inst(op_type));
193
0
    // [dividend:op_type 1:op_type divisor:op_type is_zero:i32]
194
0
    insts.push(Instruction::Select);
195
0
    // [dividend:op_type divisor:op_type]
196
0
    insts.push(inst);
197
0
    // [result:op_type]
198
0
}
199
200
0
pub(crate) fn trunc<'a>(
201
0
    inst: Instruction<'a>,
202
0
    builder: &mut CodeBuilder,
203
0
    insts: &mut Vec<Instruction<'a>>,
204
0
) {
205
0
    // If NaN or ±inf, replace with dummy value. Our method of checking for NaN
206
0
    // is to use `ne` because NaN is the only value that is not equal to itself
207
0
    let conv_type = type_of_float_conversion(&inst);
208
0
    let temp_float = builder.alloc_local(conv_type);
209
0
    // [input:conv_type]
210
0
    insts.push(Instruction::LocalTee(temp_float));
211
0
    // [input:conv_type]
212
0
    insts.push(Instruction::LocalGet(temp_float));
213
0
    // [input:conv_type input:conv_type]
214
0
    insts.push(ne_inst(conv_type));
215
0
    // [is_nan:i32]
216
0
    insts.push(Instruction::LocalGet(temp_float));
217
0
    // [is_nan:i32 input:conv_type]
218
0
    insts.push(flt_inf_const_inst(conv_type));
219
0
    // [is_nan:i32 input:conv_type inf:conv_type]
220
0
    insts.push(eq_inst(conv_type));
221
0
    // [is_nan:i32 is_inf:i32]
222
0
    insts.push(Instruction::LocalGet(temp_float));
223
0
    // [is_nan:i32 is_inf:i32 input:conv_type]
224
0
    insts.push(flt_neg_inf_const_inst(conv_type));
225
0
    // [is_nan:i32 is_inf:i32 input:conv_type neg_inf:conv_type]
226
0
    insts.push(eq_inst(conv_type));
227
0
    // [is_nan:i32 is_inf:i32 is_neg_inf:i32]
228
0
    insts.push(Instruction::I32Or);
229
0
    // [is_nan:i32 is_±inf:i32]
230
0
    insts.push(Instruction::I32Or);
231
0
    // [is_nan_or_inf:i32]
232
0
    insts.push(Instruction::If(BlockType::Empty));
233
0
    {
234
0
        // []
235
0
        insts.push(dummy_value_inst(conv_type));
236
0
        // [0:conv_type]
237
0
        insts.push(Instruction::LocalSet(temp_float));
238
0
        // []
239
0
    }
240
0
    insts.push(Instruction::End);
241
0
    // []
242
0
    insts.push(Instruction::LocalGet(temp_float));
243
0
    // [input_or_0:conv_type]
244
0
245
0
    // first ensure that it is >= the min value of our target type
246
0
    insts.push(min_input_const_for_trunc(&inst));
247
0
    // [input_or_0:conv_type min_value_of_target_type:conv_type]
248
0
    insts.push(flt_lt_inst(conv_type));
249
0
    // [input_lt_min:i32]
250
0
    insts.push(Instruction::If(BlockType::Empty));
251
0
    {
252
0
        // []
253
0
        insts.push(min_input_const_for_trunc(&inst));
254
0
        // [min_value_of_target_type:conv_type]
255
0
        insts.push(Instruction::LocalSet(temp_float));
256
0
    }
257
0
    insts.push(Instruction::End);
258
0
    // []
259
0
    insts.push(Instruction::LocalGet(temp_float));
260
0
    // [coerced_input:conv_type]
261
0
262
0
    // next ensure that it is  <= the max value of our target type
263
0
    insts.push(max_input_const_for_trunc(&inst));
264
0
    // [input_or_0:conv_type max_value_of_target_type:conv_type]
265
0
    insts.push(flt_gt_inst(conv_type));
266
0
    // [input_gt_min:i32]
267
0
    insts.push(Instruction::If(BlockType::Empty));
268
0
    {
269
0
        // []
270
0
        insts.push(max_input_const_for_trunc(&inst));
271
0
        // [max_value_of_target_type:conv_type]
272
0
        insts.push(Instruction::LocalSet(temp_float));
273
0
    }
274
0
    insts.push(Instruction::End);
275
0
    // []
276
0
    insts.push(Instruction::LocalGet(temp_float));
277
0
    // [coerced_input:conv_type]
278
0
    insts.push(inst);
279
0
}
280
281
// Signed division and remainder will trap in the following instances:
282
//     - The divisor is 0
283
//     - The result of the division is 2^(n-1)
284
0
pub(crate) fn signed_div_rem<'a>(
285
0
    inst: Instruction<'a>,
286
0
    builder: &mut CodeBuilder,
287
0
    insts: &mut Vec<Instruction<'a>>,
288
0
) {
289
0
    // If divisor is 0, replace with 1
290
0
    let op_type = type_of_integer_operation(&inst);
291
0
    let temp_divisor = builder.alloc_local(op_type);
292
0
    // [dividend:op_type divisor:op_type]
293
0
    insts.push(Instruction::LocalSet(temp_divisor));
294
0
    // [dividend:op_type]
295
0
    insts.push(int_const_inst(op_type, 1));
296
0
    // [dividend:op_type 1:op_type]
297
0
    insts.push(Instruction::LocalGet(temp_divisor));
298
0
    // [dividend:op_type 1:op_type divisor:op_type]
299
0
    insts.push(Instruction::LocalGet(temp_divisor));
300
0
    // [dividend:op_type 1:op_type divisor:op_type divisor:op_type]
301
0
    insts.push(eqz_inst(op_type));
302
0
    // [dividend:op_type 1:op_type divisor:op_type is_zero:i32]
303
0
    insts.push(Instruction::Select);
304
0
    // [dividend:op_type divisor:op_type]
305
0
    // If dividend and divisor are -int.max and -1, replace
306
0
    // divisor with 1.
307
0
    let temp_dividend = builder.alloc_local(op_type);
308
0
    insts.push(Instruction::LocalSet(temp_divisor));
309
0
    // [dividend:op_type]
310
0
    insts.push(Instruction::LocalSet(temp_dividend));
311
0
    // []
312
0
    insts.push(Instruction::Block(wasm_encoder::BlockType::Empty));
313
0
    {
314
0
        insts.push(Instruction::Block(wasm_encoder::BlockType::Empty));
315
0
        {
316
0
            // []
317
0
            insts.push(Instruction::LocalGet(temp_dividend));
318
0
            // [dividend:op_type]
319
0
            insts.push(Instruction::LocalGet(temp_divisor));
320
0
            // [dividend:op_type divisor:op_type]
321
0
            insts.push(Instruction::LocalSet(temp_divisor));
322
0
            // [dividend:op_type]
323
0
            insts.push(Instruction::LocalTee(temp_dividend));
324
0
            // [dividend:op_type]
325
0
            insts.push(int_min_const_inst(op_type));
326
0
            // [dividend:op_type int_min:op_type]
327
0
            insts.push(ne_inst(op_type));
328
0
            // [not_int_min:i32]
329
0
            insts.push(Instruction::BrIf(0));
330
0
            // []
331
0
            insts.push(Instruction::LocalGet(temp_divisor));
332
0
            // [divisor:op_type]
333
0
            insts.push(int_const_inst(op_type, -1));
334
0
            // [divisor:op_type -1:op_type]
335
0
            insts.push(ne_inst(op_type));
336
0
            // [not_neg_one:i32]
337
0
            insts.push(Instruction::BrIf(0));
338
0
            // []
339
0
            insts.push(int_const_inst(op_type, 1));
340
0
            // [divisor:op_type]
341
0
            insts.push(Instruction::LocalSet(temp_divisor));
342
0
            // []
343
0
            insts.push(Instruction::Br(1));
344
0
        }
345
0
        // []
346
0
        insts.push(Instruction::End);
347
0
    }
348
0
    // []
349
0
    insts.push(Instruction::End);
350
0
    // []
351
0
    insts.push(Instruction::LocalGet(temp_dividend));
352
0
    // [dividend:op_type]
353
0
    insts.push(Instruction::LocalGet(temp_divisor));
354
0
    // [dividend:op_type divisor:op_type]
355
0
    insts.push(inst);
356
0
}
357
358
0
fn get_memarg(inst: &Instruction) -> wasm_encoder::MemArg {
359
0
    match *inst {
360
0
        Instruction::I32Load(memarg)
361
0
        | Instruction::I64Load(memarg)
362
0
        | Instruction::F32Load(memarg)
363
0
        | Instruction::F64Load(memarg)
364
0
        | Instruction::I32Load8S(memarg)
365
0
        | Instruction::I32Load8U(memarg)
366
0
        | Instruction::I32Load16S(memarg)
367
0
        | Instruction::I32Load16U(memarg)
368
0
        | Instruction::I64Load8S(memarg)
369
0
        | Instruction::I64Load8U(memarg)
370
0
        | Instruction::I64Load16S(memarg)
371
0
        | Instruction::I64Load16U(memarg)
372
0
        | Instruction::I64Load32S(memarg)
373
0
        | Instruction::I64Load32U(memarg)
374
0
        | Instruction::V128Load(memarg)
375
0
        | Instruction::V128Load8x8S(memarg)
376
0
        | Instruction::V128Load8x8U(memarg)
377
0
        | Instruction::V128Load16x4S(memarg)
378
0
        | Instruction::V128Load16x4U(memarg)
379
0
        | Instruction::V128Load32x2S(memarg)
380
0
        | Instruction::V128Load32x2U(memarg)
381
0
        | Instruction::V128Load8Splat(memarg)
382
0
        | Instruction::V128Load16Splat(memarg)
383
0
        | Instruction::V128Load32Splat(memarg)
384
0
        | Instruction::V128Load64Splat(memarg)
385
0
        | Instruction::V128Load32Zero(memarg)
386
0
        | Instruction::V128Load64Zero(memarg)
387
0
        | Instruction::I32Store(memarg)
388
0
        | Instruction::I64Store(memarg)
389
0
        | Instruction::F32Store(memarg)
390
0
        | Instruction::F64Store(memarg)
391
0
        | Instruction::I32Store8(memarg)
392
0
        | Instruction::I32Store16(memarg)
393
0
        | Instruction::I64Store8(memarg)
394
0
        | Instruction::I64Store16(memarg)
395
0
        | Instruction::I64Store32(memarg)
396
0
        | Instruction::V128Store(memarg) => memarg,
397
0
        _ => unreachable!(),
398
    }
399
0
}
400
401
0
fn dummy_value_inst<'a>(ty: ValType) -> Instruction<'a> {
402
0
    match ty {
403
0
        ValType::I32 => Instruction::I32Const(0),
404
0
        ValType::I64 => Instruction::I64Const(0),
405
0
        ValType::F32 => Instruction::F32Const(0.0),
406
0
        ValType::F64 => Instruction::F64Const(0.0),
407
0
        ValType::V128 => Instruction::V128Const(0),
408
0
        ValType::Ref(ty) => {
409
0
            assert!(ty.nullable);
410
0
            Instruction::RefNull(ty.heap_type)
411
        }
412
    }
413
0
}
414
415
0
fn eq_inst<'a>(ty: ValType) -> Instruction<'a> {
416
0
    match ty {
417
0
        ValType::F32 => Instruction::F32Eq,
418
0
        ValType::F64 => Instruction::F64Eq,
419
0
        ValType::I32 => Instruction::I32Eq,
420
0
        ValType::I64 => Instruction::I64Eq,
421
0
        _ => panic!("not a numeric type"),
422
    }
423
0
}
424
425
0
fn eqz_inst<'a>(ty: ValType) -> Instruction<'a> {
426
0
    match ty {
427
0
        ValType::I32 => Instruction::I32Eqz,
428
0
        ValType::I64 => Instruction::I64Eqz,
429
0
        _ => panic!("not an integer type"),
430
    }
431
0
}
432
433
0
fn type_of_integer_operation(inst: &Instruction) -> ValType {
434
0
    match inst {
435
        Instruction::I32DivU
436
        | Instruction::I32DivS
437
        | Instruction::I32RemU
438
0
        | Instruction::I32RemS => ValType::I32,
439
        Instruction::I64RemU
440
        | Instruction::I64DivU
441
        | Instruction::I64DivS
442
0
        | Instruction::I64RemS => ValType::I64,
443
0
        _ => panic!("not integer division or remainder"),
444
    }
445
0
}
446
447
0
fn type_of_float_conversion(inst: &Instruction) -> ValType {
448
0
    match inst {
449
        Instruction::I32TruncF32S
450
        | Instruction::I32TruncF32U
451
        | Instruction::I64TruncF32S
452
0
        | Instruction::I64TruncF32U => ValType::F32,
453
        Instruction::I32TruncF64S
454
        | Instruction::I32TruncF64U
455
        | Instruction::I64TruncF64S
456
0
        | Instruction::I64TruncF64U => ValType::F64,
457
0
        _ => panic!("not a float -> integer conversion"),
458
    }
459
0
}
460
461
0
fn min_input_const_for_trunc<'a>(inst: &Instruction) -> Instruction<'a> {
462
0
    // This is the minimum float value that is representable as an i64
463
0
    let min_f64 = -9_223_372_036_854_775_000f64;
464
0
    let min_f32 = -9_223_372_000_000_000_000f32;
465
0
466
0
    // This is the minimum float value that is representable as as i32
467
0
    let min_f32_as_i32 = -2_147_483_500f32;
468
0
    match inst {
469
0
        Instruction::I32TruncF32S => Instruction::F32Const(min_f32_as_i32),
470
0
        Instruction::I32TruncF32U => Instruction::F32Const(0.0),
471
0
        Instruction::I64TruncF32S => Instruction::F32Const(min_f32),
472
0
        Instruction::I64TruncF32U => Instruction::F32Const(0.0),
473
0
        Instruction::I32TruncF64S => Instruction::F64Const(i32::MIN as f64),
474
0
        Instruction::I32TruncF64U => Instruction::F64Const(0.0),
475
0
        Instruction::I64TruncF64S => Instruction::F64Const(min_f64),
476
0
        Instruction::I64TruncF64U => Instruction::F64Const(0.0),
477
0
        _ => panic!("not a trunc instruction"),
478
    }
479
0
}
480
481
0
fn max_input_const_for_trunc<'a>(inst: &Instruction) -> Instruction<'a> {
482
0
    // This is the maximum float value that is representable as as i64
483
0
    let max_f64_as_i64 = 9_223_372_036_854_775_000f64;
484
0
    let max_f32_as_i64 = 9_223_371_500_000_000_000f32;
485
0
486
0
    // This is the maximum float value that is representable as as i32
487
0
    let max_f32_as_i32 = 2_147_483_500f32;
488
0
    match inst {
489
        Instruction::I32TruncF32S | Instruction::I32TruncF32U => {
490
0
            Instruction::F32Const(max_f32_as_i32)
491
        }
492
        Instruction::I64TruncF32S | Instruction::I64TruncF32U => {
493
0
            Instruction::F32Const(max_f32_as_i64)
494
        }
495
        Instruction::I32TruncF64S | Instruction::I32TruncF64U => {
496
0
            Instruction::F64Const(i32::MAX as f64)
497
        }
498
        Instruction::I64TruncF64S | Instruction::I64TruncF64U => {
499
0
            Instruction::F64Const(max_f64_as_i64)
500
        }
501
0
        _ => panic!("not a trunc instruction"),
502
    }
503
0
}
504
505
0
fn type_of_memory_access(inst: &Instruction) -> ValType {
506
0
    match inst {
507
        Instruction::I32Load(_)
508
        | Instruction::I32Load8S(_)
509
        | Instruction::I32Load8U(_)
510
        | Instruction::I32Load16S(_)
511
        | Instruction::I32Load16U(_)
512
        | Instruction::I32Store(_)
513
        | Instruction::I32Store8(_)
514
0
        | Instruction::I32Store16(_) => ValType::I32,
515
516
        Instruction::I64Load(_)
517
        | Instruction::I64Load8S(_)
518
        | Instruction::I64Load8U(_)
519
        | Instruction::I64Load16S(_)
520
        | Instruction::I64Load16U(_)
521
        | Instruction::I64Load32S(_)
522
        | Instruction::I64Load32U(_)
523
        | Instruction::I64Store(_)
524
        | Instruction::I64Store8(_)
525
        | Instruction::I64Store16(_)
526
0
        | Instruction::I64Store32(_) => ValType::I64,
527
528
0
        Instruction::F32Load(_) | Instruction::F32Store(_) => ValType::F32,
529
530
0
        Instruction::F64Load(_) | Instruction::F64Store(_) => ValType::F64,
531
532
        Instruction::V128Load { .. }
533
        | Instruction::V128Load8x8S { .. }
534
        | Instruction::V128Load8x8U { .. }
535
        | Instruction::V128Load16x4S { .. }
536
        | Instruction::V128Load16x4U { .. }
537
        | Instruction::V128Load32x2S { .. }
538
        | Instruction::V128Load32x2U { .. }
539
        | Instruction::V128Load8Splat { .. }
540
        | Instruction::V128Load16Splat { .. }
541
        | Instruction::V128Load32Splat { .. }
542
        | Instruction::V128Load64Splat { .. }
543
        | Instruction::V128Load32Zero { .. }
544
        | Instruction::V128Load64Zero { .. }
545
0
        | Instruction::V128Store { .. } => ValType::V128,
546
547
0
        _ => panic!("not a memory access instruction"),
548
    }
549
0
}
550
551
0
fn int_min_const_inst<'a>(ty: ValType) -> Instruction<'a> {
552
0
    match ty {
553
0
        ValType::I32 => Instruction::I32Const(i32::MIN),
554
0
        ValType::I64 => Instruction::I64Const(i64::MIN),
555
0
        _ => panic!("not an int type"),
556
    }
557
0
}
558
559
0
fn int_const_inst<'a>(ty: ValType, x: i64) -> Instruction<'a> {
560
0
    match ty {
561
0
        ValType::I32 => Instruction::I32Const(x as i32),
562
0
        ValType::I64 => Instruction::I64Const(x),
563
0
        _ => panic!("not an int type"),
564
    }
565
0
}
566
567
0
fn int_mul_inst<'a>(ty: ValType) -> Instruction<'a> {
568
0
    match ty {
569
0
        ValType::I32 => Instruction::I32Mul,
570
0
        ValType::I64 => Instruction::I64Mul,
571
0
        _ => panic!("not an int type"),
572
    }
573
0
}
574
575
0
fn int_add_inst<'a>(ty: ValType) -> Instruction<'a> {
576
0
    match ty {
577
0
        ValType::I32 => Instruction::I32Add,
578
0
        ValType::I64 => Instruction::I64Add,
579
0
        _ => panic!("not an int type"),
580
    }
581
0
}
582
583
0
fn int_le_u_inst<'a>(ty: ValType) -> Instruction<'a> {
584
0
    match ty {
585
0
        ValType::I32 => Instruction::I32LeU,
586
0
        ValType::I64 => Instruction::I64LeU,
587
0
        _ => panic!("not an int type"),
588
    }
589
0
}
590
591
0
fn int_le_s_inst<'a>(ty: ValType) -> Instruction<'a> {
592
0
    match ty {
593
0
        ValType::I32 => Instruction::I32LeS,
594
0
        ValType::I64 => Instruction::I64LeS,
595
0
        _ => panic!("not an int type"),
596
    }
597
0
}
598
599
0
fn ne_inst<'a>(ty: ValType) -> Instruction<'a> {
600
0
    match ty {
601
0
        ValType::I32 => Instruction::I32Ne,
602
0
        ValType::I64 => Instruction::I64Ne,
603
0
        ValType::F32 => Instruction::F32Ne,
604
0
        ValType::F64 => Instruction::F64Ne,
605
0
        _ => panic!("not a numeric type"),
606
    }
607
0
}
608
609
0
fn flt_lt_inst<'a>(ty: ValType) -> Instruction<'a> {
610
0
    match ty {
611
0
        ValType::F32 => Instruction::F32Lt,
612
0
        ValType::F64 => Instruction::F64Lt,
613
0
        _ => panic!("not a float type"),
614
    }
615
0
}
616
617
0
fn flt_gt_inst<'a>(ty: ValType) -> Instruction<'a> {
618
0
    match ty {
619
0
        ValType::F32 => Instruction::F32Gt,
620
0
        ValType::F64 => Instruction::F64Gt,
621
0
        _ => panic!("not a float type"),
622
    }
623
0
}
624
625
0
fn flt_inf_const_inst<'a>(ty: ValType) -> Instruction<'a> {
626
0
    match ty {
627
0
        ValType::F32 => Instruction::F32Const(f32::INFINITY),
628
0
        ValType::F64 => Instruction::F64Const(f64::INFINITY),
629
0
        _ => panic!("not a float type"),
630
    }
631
0
}
632
633
0
fn flt_neg_inf_const_inst<'a>(ty: ValType) -> Instruction<'a> {
634
0
    match ty {
635
0
        ValType::F32 => Instruction::F32Const(f32::NEG_INFINITY),
636
0
        ValType::F64 => Instruction::F64Const(f64::NEG_INFINITY),
637
0
        _ => panic!("not a float type"),
638
    }
639
0
}
640
641
0
fn size_of_type_in_memory(ty: ValType) -> u64 {
642
0
    match ty {
643
0
        ValType::I32 => 4,
644
0
        ValType::I64 => 8,
645
0
        ValType::F32 => 4,
646
0
        ValType::F64 => 8,
647
0
        ValType::V128 => 16,
648
0
        ValType::Ref(_) => panic!("not a memory type"),
649
    }
650
0
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/core/encode.rs
Line
Count
Source (jump to first uncovered line)
1
use super::*;
2
3
impl Module {
4
    /// Encode this Wasm module into bytes.
5
5.67k
    pub fn to_bytes(&self) -> Vec<u8> {
6
5.67k
        self.encoded().finish()
7
5.67k
    }
8
9
5.67k
    fn encoded(&self) -> wasm_encoder::Module {
10
5.67k
        let mut module = wasm_encoder::Module::new();
11
5.67k
12
5.67k
        self.encode_types(&mut module);
13
5.67k
        self.encode_imports(&mut module);
14
5.67k
        self.encode_funcs(&mut module);
15
5.67k
        self.encode_tables(&mut module);
16
5.67k
        self.encode_memories(&mut module);
17
5.67k
        self.encode_tags(&mut module);
18
5.67k
        self.encode_globals(&mut module);
19
5.67k
        self.encode_exports(&mut module);
20
5.67k
        self.encode_start(&mut module);
21
5.67k
        self.encode_elems(&mut module);
22
5.67k
        self.encode_data_count(&mut module);
23
5.67k
        self.encode_code(&mut module);
24
5.67k
        self.encode_data(&mut module);
25
5.67k
26
5.67k
        module
27
5.67k
    }
28
29
5.67k
    fn encode_types(&self, module: &mut wasm_encoder::Module) {
30
5.67k
        if !self.should_encode_types {
31
1.03k
            return;
32
4.63k
        }
33
4.63k
34
4.63k
        let mut section = wasm_encoder::TypeSection::new();
35
36
10.3k
        for group in &self.rec_groups {
37
5.68k
            if group.end - group.start == 1 {
38
5.68k
                let ty = &self.types[group.start];
39
5.68k
                section.subtype(&wasm_encoder::SubType {
40
5.68k
                    is_final: ty.is_final,
41
5.68k
                    supertype_idx: ty.supertype,
42
5.68k
                    composite_type: match &ty.composite_type {
43
0
                        CompositeType::Array(a) => wasm_encoder::CompositeType::Array(a.clone()),
44
5.68k
                        CompositeType::Func(f) => {
45
5.68k
                            wasm_encoder::CompositeType::Func(wasm_encoder::FuncType::new(
46
5.68k
                                f.params.iter().cloned(),
47
5.68k
                                f.results.iter().cloned(),
48
5.68k
                            ))
49
                        }
50
0
                        CompositeType::Struct(s) => wasm_encoder::CompositeType::Struct(s.clone()),
51
                    },
52
                });
53
0
            } else {
54
0
                section.rec(
55
0
                    self.types[group.clone()]
56
0
                        .iter()
57
0
                        .map(|ty| wasm_encoder::SubType {
58
0
                            is_final: ty.is_final,
59
0
                            supertype_idx: ty.supertype,
60
0
                            composite_type: match &ty.composite_type {
61
0
                                CompositeType::Array(a) => {
62
0
                                    wasm_encoder::CompositeType::Array(a.clone())
63
                                }
64
0
                                CompositeType::Func(f) => {
65
0
                                    wasm_encoder::CompositeType::Func(wasm_encoder::FuncType::new(
66
0
                                        f.params.iter().cloned(),
67
0
                                        f.results.iter().cloned(),
68
0
                                    ))
69
                                }
70
0
                                CompositeType::Struct(s) => {
71
0
                                    wasm_encoder::CompositeType::Struct(s.clone())
72
                                }
73
                            },
74
0
                        }),
75
0
                );
76
0
            }
77
        }
78
79
4.63k
        module.section(&section);
80
5.67k
    }
81
82
5.67k
    fn encode_imports(&self, module: &mut wasm_encoder::Module) {
83
5.67k
        if !self.should_encode_imports {
84
3.11k
            return;
85
2.55k
        }
86
2.55k
87
2.55k
        let mut section = wasm_encoder::ImportSection::new();
88
6.87k
        for im in &self.imports {
89
4.32k
            section.import(
90
4.32k
                &im.module,
91
4.32k
                &im.field,
92
4.32k
                translate_entity_type(&im.entity_type),
93
4.32k
            );
94
4.32k
        }
95
2.55k
        module.section(&section);
96
5.67k
    }
97
98
5.67k
    fn encode_tags(&self, module: &mut wasm_encoder::Module) {
99
5.67k
        if self.num_defined_tags == 0 {
100
5.67k
            return;
101
0
        }
102
0
        let mut tags = wasm_encoder::TagSection::new();
103
0
        for tag in self.tags[self.tags.len() - self.num_defined_tags..].iter() {
104
0
            tags.tag(wasm_encoder::TagType {
105
0
                kind: wasm_encoder::TagKind::Exception,
106
0
                func_type_idx: tag.func_type_idx,
107
0
            });
108
0
        }
109
0
        module.section(&tags);
110
5.67k
    }
111
112
5.67k
    fn encode_funcs(&self, module: &mut wasm_encoder::Module) {
113
5.67k
        if self.num_defined_funcs == 0 {
114
1.57k
            return;
115
4.09k
        }
116
4.09k
        let mut funcs = wasm_encoder::FunctionSection::new();
117
15.8k
        for (ty, _) in self.funcs[self.funcs.len() - self.num_defined_funcs..].iter() {
118
15.8k
            funcs.function(*ty);
119
15.8k
        }
120
4.09k
        module.section(&funcs);
121
5.67k
    }
122
123
5.67k
    fn encode_tables(&self, module: &mut wasm_encoder::Module) {
124
5.67k
        if self.defined_tables.is_empty() {
125
4.63k
            return;
126
1.03k
        }
127
1.03k
        let mut tables = wasm_encoder::TableSection::new();
128
1.03k
        for (t, init) in self.tables[self.tables.len() - self.defined_tables.len()..]
129
1.03k
            .iter()
130
1.03k
            .zip(&self.defined_tables)
131
        {
132
1.03k
            match init {
133
0
                Some(init) => {
134
0
                    tables.table_with_init(*t, init);
135
0
                }
136
1.03k
                None => {
137
1.03k
                    tables.table(*t);
138
1.03k
                }
139
            }
140
        }
141
1.03k
        module.section(&tables);
142
5.67k
    }
143
144
5.67k
    fn encode_memories(&self, module: &mut wasm_encoder::Module) {
145
5.67k
        if self.num_defined_memories == 0 {
146
4.26k
            return;
147
1.41k
        }
148
1.41k
        let mut mems = wasm_encoder::MemorySection::new();
149
1.41k
        for m in self.memories[self.memories.len() - self.num_defined_memories..].iter() {
150
1.41k
            mems.memory(*m);
151
1.41k
        }
152
1.41k
        module.section(&mems);
153
5.67k
    }
154
155
5.67k
    fn encode_globals(&self, module: &mut wasm_encoder::Module) {
156
5.67k
        if self.globals.is_empty() {
157
3.99k
            return;
158
1.67k
        }
159
1.67k
        let mut globals = wasm_encoder::GlobalSection::new();
160
5.19k
        for (idx, expr) in &self.defined_globals {
161
3.51k
            let ty = &self.globals[*idx as usize];
162
3.51k
            globals.global(*ty, expr);
163
3.51k
        }
164
1.67k
        module.section(&globals);
165
5.67k
    }
166
167
5.67k
    fn encode_exports(&self, module: &mut wasm_encoder::Module) {
168
5.67k
        if self.exports.is_empty() {
169
4.77k
            return;
170
897
        }
171
897
        let mut exports = wasm_encoder::ExportSection::new();
172
6.36k
        for (name, kind, idx) in &self.exports {
173
5.46k
            exports.export(name, *kind, *idx);
174
5.46k
        }
175
897
        module.section(&exports);
176
5.67k
    }
177
178
5.67k
    fn encode_start(&self, module: &mut wasm_encoder::Module) {
179
5.67k
        if let Some(f) = self.start {
180
582
            module.section(&wasm_encoder::StartSection { function_index: f });
181
5.09k
        }
182
5.67k
    }
183
184
5.67k
    fn encode_elems(&self, module: &mut wasm_encoder::Module) {
185
5.67k
        if self.elems.is_empty() {
186
5.42k
            return;
187
252
        }
188
252
        let mut elems = wasm_encoder::ElementSection::new();
189
1.84k
        for el in &self.elems {
190
1.58k
            let elements = match &el.items {
191
0
                Elements::Expressions(es) => wasm_encoder::Elements::Expressions(el.ty, es),
192
1.58k
                Elements::Functions(fs) => {
193
1.58k
                    assert_eq!(el.ty, RefType::FUNCREF);
194
1.58k
                    wasm_encoder::Elements::Functions(fs)
195
                }
196
            };
197
1.58k
            match &el.kind {
198
1.58k
                ElementKind::Active { table, offset } => {
199
1.58k
                    let offset = match *offset {
200
1.20k
                        Offset::Const32(n) => ConstExpr::i32_const(n),
201
0
                        Offset::Const64(n) => ConstExpr::i64_const(n),
202
383
                        Offset::Global(g) => ConstExpr::global_get(g),
203
                    };
204
1.58k
                    elems.active(*table, &offset, elements);
205
                }
206
0
                ElementKind::Passive => {
207
0
                    elems.passive(elements);
208
0
                }
209
0
                ElementKind::Declared => {
210
0
                    elems.declared(elements);
211
0
                }
212
            }
213
        }
214
252
        module.section(&elems);
215
5.67k
    }
216
217
5.67k
    fn encode_data_count(&self, module: &mut wasm_encoder::Module) {
218
5.67k
        // Without bulk memory there's no need for a data count section,
219
5.67k
        if !self.config.bulk_memory_enabled {
220
5.67k
            return;
221
0
        }
222
0
        // ... and also if there's no data no need for a data count section.
223
0
        if self.data.is_empty() {
224
0
            return;
225
0
        }
226
0
        module.section(&wasm_encoder::DataCountSection {
227
0
            count: u32::try_from(self.data.len()).unwrap(),
228
0
        });
229
5.67k
    }
230
231
5.67k
    fn encode_code(&self, module: &mut wasm_encoder::Module) {
232
5.67k
        if self.code.is_empty() {
233
1.57k
            return;
234
4.09k
        }
235
4.09k
        let mut code = wasm_encoder::CodeSection::new();
236
19.8k
        for c in &self.code {
237
            // Skip the run-length encoding because it is a little
238
            // annoying to compute; use a length of one for every local.
239
15.8k
            let mut func = wasm_encoder::Function::new(c.locals.iter().map(|l| (1, *l)));
240
15.8k
            match &c.instructions {
241
15.8k
                Instructions::Generated(instrs) => {
242
125k
                    for instr in instrs {
243
109k
                        func.instruction(instr);
244
109k
                    }
245
15.8k
                    func.instruction(&wasm_encoder::Instruction::End);
246
                }
247
0
                Instructions::Arbitrary(body) => {
248
0
                    func.raw(body.iter().copied());
249
0
                }
250
            }
251
15.8k
            code.function(&func);
252
        }
253
4.09k
        module.section(&code);
254
5.67k
    }
255
256
5.67k
    fn encode_data(&self, module: &mut wasm_encoder::Module) {
257
5.67k
        if self.data.is_empty() {
258
5.49k
            return;
259
176
        }
260
176
        let mut data = wasm_encoder::DataSection::new();
261
952
        for seg in &self.data {
262
776
            match &seg.kind {
263
                DataSegmentKind::Active {
264
776
                    memory_index,
265
776
                    offset,
266
776
                } => {
267
776
                    let offset = match *offset {
268
414
                        Offset::Const32(n) => ConstExpr::i32_const(n),
269
0
                        Offset::Const64(n) => ConstExpr::i64_const(n),
270
362
                        Offset::Global(g) => ConstExpr::global_get(g),
271
                    };
272
776
                    data.active(*memory_index, &offset, seg.init.iter().copied());
273
                }
274
0
                DataSegmentKind::Passive => {
275
0
                    data.passive(seg.init.iter().copied());
276
0
                }
277
            }
278
        }
279
176
        module.section(&data);
280
5.67k
    }
281
}
282
283
4.32k
pub(crate) fn translate_entity_type(ty: &EntityType) -> wasm_encoder::EntityType {
284
4.32k
    match ty {
285
0
        EntityType::Tag(t) => wasm_encoder::EntityType::Tag(wasm_encoder::TagType {
286
0
            kind: wasm_encoder::TagKind::Exception,
287
0
            func_type_idx: t.func_type_idx,
288
0
        }),
289
1.56k
        EntityType::Func(f, _) => wasm_encoder::EntityType::Function(*f),
290
288
        EntityType::Table(ty) => (*ty).into(),
291
336
        EntityType::Memory(m) => (*m).into(),
292
2.13k
        EntityType::Global(g) => (*g).into(),
293
    }
294
4.32k
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/core/terminate.rs
Line
Count
Source (jump to first uncovered line)
1
use super::*;
2
use anyhow::{bail, Result};
3
4
impl Module {
5
    /// Ensure that all of this Wasm module's functions will terminate when
6
    /// executed.
7
    ///
8
    /// This adds a new mutable, exported global to the module to keep track of
9
    /// how much "fuel" is left. Fuel is decremented at the head of each loop
10
    /// and function. When fuel reaches zero, a trap is raised.
11
    ///
12
    /// The index of the fuel global is returned, so that you may control how
13
    /// much fuel the module is given.
14
    ///
15
    /// # Errors
16
    ///
17
    /// Returns an error if any function body was generated with
18
    /// possibly-invalid bytes rather than being generated by wasm-smith. In
19
    /// such a situation this pass does not parse the input bytes and inject
20
    /// instructions, instead it returns an error.
21
0
    pub fn ensure_termination(&mut self, default_fuel: u32) -> Result<u32> {
22
0
        let fuel_global = self.globals.len() as u32;
23
0
        self.globals.push(GlobalType {
24
0
            val_type: ValType::I32,
25
0
            mutable: true,
26
0
            shared: false,
27
0
        });
28
0
        self.defined_globals
29
0
            .push((fuel_global, ConstExpr::i32_const(default_fuel as i32)));
30
31
0
        for code in &mut self.code {
32
0
            let check_fuel = |insts: &mut Vec<Instruction>| {
33
0
                // if fuel == 0 { trap }
34
0
                insts.push(Instruction::GlobalGet(fuel_global));
35
0
                insts.push(Instruction::I32Eqz);
36
0
                insts.push(Instruction::If(BlockType::Empty));
37
0
                insts.push(Instruction::Unreachable);
38
0
                insts.push(Instruction::End);
39
0
40
0
                // fuel -= 1
41
0
                insts.push(Instruction::GlobalGet(fuel_global));
42
0
                insts.push(Instruction::I32Const(1));
43
0
                insts.push(Instruction::I32Sub);
44
0
                insts.push(Instruction::GlobalSet(fuel_global));
45
0
            };
46
47
0
            let instrs = match &mut code.instructions {
48
0
                Instructions::Generated(list) => list,
49
                Instructions::Arbitrary(_) => {
50
0
                    bail!(
51
0
                        "failed to ensure that a function generated due to it \
52
0
                         containing arbitrary instructions"
53
0
                    )
54
                }
55
            };
56
0
            let mut new_insts = Vec::with_capacity(instrs.len() * 2);
57
0
58
0
            // Check fuel at the start of functions to deal with infinite
59
0
            // recursion.
60
0
            check_fuel(&mut new_insts);
61
62
0
            for inst in mem::replace(instrs, vec![]) {
63
0
                let is_loop = matches!(&inst, Instruction::Loop(_));
64
0
                new_insts.push(inst);
65
0
66
0
                // Check fuel at loop heads to deal with infinite loops.
67
0
                if is_loop {
68
0
                    check_fuel(&mut new_insts);
69
0
                }
70
            }
71
72
0
            *instrs = new_insts;
73
        }
74
75
0
        Ok(fuel_global)
76
0
    }
77
}
/Users/hota1024/.cargo/registry/src/index.crates.io-6f17d22bba15001f/wasm-smith-0.210.0/src/lib.rs
Line
Count
Source (jump to first uncovered line)
1
//! A WebAssembly test case generator.
2
//!
3
//! ## Usage
4
//!
5
//! First, use [`cargo fuzz`](https://github.com/rust-fuzz/cargo-fuzz) to define
6
//! a new fuzz target:
7
//!
8
//! ```shell
9
//! $ cargo fuzz add my_wasm_smith_fuzz_target
10
//! ```
11
//!
12
//! Next, add `wasm-smith` to your dependencies:
13
//!
14
//! ```shell
15
//! $ cargo add wasm-smith
16
//! ```
17
//!
18
//! Then, define your fuzz target so that it takes arbitrary
19
//! `wasm_smith::Module`s as an argument, convert the module into serialized
20
//! Wasm bytes via the `to_bytes` method, and then feed it into your system:
21
//!
22
//! ```no_run
23
//! // fuzz/fuzz_targets/my_wasm_smith_fuzz_target.rs
24
//!
25
//! #![no_main]
26
//!
27
//! use libfuzzer_sys::fuzz_target;
28
//! use wasm_smith::Module;
29
//!
30
//! fuzz_target!(|module: Module| {
31
//!     let wasm_bytes = module.to_bytes();
32
//!
33
//!     // Your code here...
34
//! });
35
//! ```
36
//!
37
//! Finally, start fuzzing:
38
//!
39
//! ```shell
40
//! $ cargo fuzz run my_wasm_smith_fuzz_target
41
//! ```
42
//!
43
//! > **Note:** For a real world example, also check out [the `validate` fuzz
44
//! > target](https://github.com/fitzgen/wasm-smith/blob/main/fuzz/fuzz_targets/validate.rs)
45
//! > defined in this repository. Using the `wasmparser` crate, it checks that
46
//! > every module generated by `wasm-smith` validates successfully.
47
//!
48
//! ## Design
49
//!
50
//! The design and implementation strategy of wasm-smith is outlined in
51
//! [this article](https://fitzgeraldnick.com/2020/08/24/writing-a-test-case-generator.html).
52
53
#![deny(missing_docs, missing_debug_implementations)]
54
// Needed for the `instructions!` macro in `src/code_builder.rs`.
55
#![recursion_limit = "512"]
56
57
mod component;
58
mod config;
59
mod core;
60
61
pub use crate::core::{InstructionKind, InstructionKinds, Module};
62
use arbitrary::{Result, Unstructured};
63
pub use component::Component;
64
pub use config::{Config, MemoryOffsetChoices};
65
use std::{collections::HashSet, fmt::Write, str};
66
use wasm_encoder::MemoryType;
67
68
#[cfg(feature = "_internal_cli")]
69
pub use config::InternalOptionalConfig;
70
71
7.15k
pub(crate) fn page_size(mem: &MemoryType) -> u32 {
72
7.15k
    const DEFAULT_WASM_PAGE_SIZE: u32 = 65_536;
73
7.15k
    mem.page_size_log2.unwrap_or(DEFAULT_WASM_PAGE_SIZE)
74
7.15k
}
75
76
/// Do something an arbitrary number of times.
77
///
78
/// The callback can return `false` to exit the loop early.
79
63.1k
pub(crate) fn arbitrary_loop<'a>(
80
63.1k
    u: &mut Unstructured<'a>,
81
63.1k
    min: usize,
82
63.1k
    max: usize,
83
63.1k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
63.1k
) -> Result<()> {
85
63.1k
    assert!(max >= min);
86
63.1k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
63.1k
    for _ in 0..(max - min) {
92
105k
        let keep_going = u.arbitrary().unwrap_or(false);
93
105k
        if !keep_going {
94
60.2k
            break;
95
45.0k
        }
96
45.0k
97
45.0k
        if !f(u)? {
98
56
            break;
99
44.9k
        }
100
    }
101
102
63.1k
    Ok(())
103
63.1k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNCNvMs3_NtB2_4coreNtBS_6Module15arbitrary_elemss3_0s0_0EB2_
Line
Count
Source
79
629
pub(crate) fn arbitrary_loop<'a>(
80
629
    u: &mut Unstructured<'a>,
81
629
    min: usize,
82
629
    max: usize,
83
629
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
629
) -> Result<()> {
85
629
    assert!(max >= min);
86
629
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
629
    for _ in 0..(max - min) {
92
2.66k
        let keep_going = u.arbitrary().unwrap_or(false);
93
2.66k
        if !keep_going {
94
247
            break;
95
2.41k
        }
96
2.41k
97
2.41k
        if !f(u)? {
98
0
            break;
99
2.41k
        }
100
    }
101
102
629
    Ok(())
103
629
}
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNCNvMs3_NtB2_4coreNtBS_6Module15arbitrary_elemss3_0s1_0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNCNvMs4_NtB2_9componentNtBS_16ComponentBuilder23arbitrary_instance_type00EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNCNvMs4_NtB2_9componentNtBS_16ComponentBuilder24arbitrary_component_type00EB2_
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module14arbitrary_datas2_0EB2_
Line
Count
Source
79
1.35k
pub(crate) fn arbitrary_loop<'a>(
80
1.35k
    u: &mut Unstructured<'a>,
81
1.35k
    min: usize,
82
1.35k
    max: usize,
83
1.35k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
1.35k
) -> Result<()> {
85
1.35k
    assert!(max >= min);
86
1.35k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
1.35k
    for _ in 0..(max - min) {
92
2.12k
        let keep_going = u.arbitrary().unwrap_or(false);
93
2.12k
        if !keep_going {
94
1.35k
            break;
95
776
        }
96
776
97
776
        if !f(u)? {
98
0
            break;
99
776
        }
100
    }
101
102
1.35k
    Ok(())
103
1.35k
}
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module14arbitrary_tags0EB2_
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module15arbitrary_elemss3_0EB2_
Line
Count
Source
79
1.13k
pub(crate) fn arbitrary_loop<'a>(
80
1.13k
    u: &mut Unstructured<'a>,
81
1.13k
    min: usize,
82
1.13k
    max: usize,
83
1.13k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
1.13k
) -> Result<()> {
85
1.13k
    assert!(max >= min);
86
1.13k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
1.13k
    for _ in 0..(max - min) {
92
2.72k
        let keep_going = u.arbitrary().unwrap_or(false);
93
2.72k
        if !keep_going {
94
1.13k
            break;
95
1.58k
        }
96
1.58k
97
1.58k
        if !f(u)? {
98
0
            break;
99
1.58k
        }
100
    }
101
102
1.13k
    Ok(())
103
1.13k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module15arbitrary_funcs0EB2_
Line
Count
Source
79
4.56k
pub(crate) fn arbitrary_loop<'a>(
80
4.56k
    u: &mut Unstructured<'a>,
81
4.56k
    min: usize,
82
4.56k
    max: usize,
83
4.56k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
4.56k
) -> Result<()> {
85
4.56k
    assert!(max >= min);
86
4.56k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
4.56k
    for _ in 0..(max - min) {
92
20.3k
        let keep_going = u.arbitrary().unwrap_or(false);
93
20.3k
        if !keep_going {
94
4.53k
            break;
95
15.8k
        }
96
15.8k
97
15.8k
        if !f(u)? {
98
2
            break;
99
15.8k
        }
100
    }
101
102
4.56k
    Ok(())
103
4.56k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module16arbitrary_locals0EB2_
Line
Count
Source
79
15.8k
pub(crate) fn arbitrary_loop<'a>(
80
15.8k
    u: &mut Unstructured<'a>,
81
15.8k
    min: usize,
82
15.8k
    max: usize,
83
15.8k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
15.8k
) -> Result<()> {
85
15.8k
    assert!(max >= min);
86
15.8k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
15.8k
    for _ in 0..(max - min) {
92
18.9k
        let keep_going = u.arbitrary().unwrap_or(false);
93
18.9k
        if !keep_going {
94
15.8k
            break;
95
3.10k
        }
96
3.10k
97
3.10k
        if !f(u)? {
98
0
            break;
99
3.10k
        }
100
    }
101
102
15.8k
    Ok(())
103
15.8k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module16arbitrary_tables0EB2_
Line
Count
Source
79
5.67k
pub(crate) fn arbitrary_loop<'a>(
80
5.67k
    u: &mut Unstructured<'a>,
81
5.67k
    min: usize,
82
5.67k
    max: usize,
83
5.67k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
5.67k
) -> Result<()> {
85
5.67k
    assert!(max >= min);
86
5.67k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
5.67k
    for _ in 0..(max - min) {
92
5.67k
        let keep_going = u.arbitrary().unwrap_or(false);
93
5.67k
        if !keep_going {
94
4.61k
            break;
95
1.06k
        }
96
1.06k
97
1.06k
        if !f(u)? {
98
21
            break;
99
1.03k
        }
100
    }
101
102
5.67k
    Ok(())
103
5.67k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module17arbitrary_exportss2_0EB2_
Line
Count
Source
79
5.67k
pub(crate) fn arbitrary_loop<'a>(
80
5.67k
    u: &mut Unstructured<'a>,
81
5.67k
    min: usize,
82
5.67k
    max: usize,
83
5.67k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
5.67k
) -> Result<()> {
85
5.67k
    assert!(max >= min);
86
5.67k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
5.67k
    for _ in 0..(max - min) {
92
10.8k
        let keep_going = u.arbitrary().unwrap_or(false);
93
10.8k
        if !keep_going {
94
5.66k
            break;
95
5.21k
        }
96
5.21k
97
5.21k
        if !f(u)? {
98
8
            break;
99
5.20k
        }
100
    }
101
102
5.67k
    Ok(())
103
5.67k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module17arbitrary_globals0EB2_
Line
Count
Source
79
5.67k
pub(crate) fn arbitrary_loop<'a>(
80
5.67k
    u: &mut Unstructured<'a>,
81
5.67k
    min: usize,
82
5.67k
    max: usize,
83
5.67k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
5.67k
) -> Result<()> {
85
5.67k
    assert!(max >= min);
86
5.67k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
5.67k
    for _ in 0..(max - min) {
92
8.17k
        let keep_going = u.arbitrary().unwrap_or(false);
93
8.17k
        if !keep_going {
94
5.67k
            break;
95
2.50k
        }
96
2.50k
97
2.50k
        if !f(u)? {
98
0
            break;
99
2.50k
        }
100
    }
101
102
5.67k
    Ok(())
103
5.67k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module17arbitrary_imports0EB2_
Line
Count
Source
79
5.67k
pub(crate) fn arbitrary_loop<'a>(
80
5.67k
    u: &mut Unstructured<'a>,
81
5.67k
    min: usize,
82
5.67k
    max: usize,
83
5.67k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
5.67k
) -> Result<()> {
85
5.67k
    assert!(max >= min);
86
5.67k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
5.67k
    for _ in 0..(max - min) {
92
9.99k
        let keep_going = u.arbitrary().unwrap_or(false);
93
9.99k
        if !keep_going {
94
5.66k
            break;
95
4.32k
        }
96
4.32k
97
4.32k
        if !f(u)? {
98
2
            break;
99
4.32k
        }
100
    }
101
102
5.67k
    Ok(())
103
5.67k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module18arbitrary_memories0EB2_
Line
Count
Source
79
5.67k
pub(crate) fn arbitrary_loop<'a>(
80
5.67k
    u: &mut Unstructured<'a>,
81
5.67k
    min: usize,
82
5.67k
    max: usize,
83
5.67k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
5.67k
) -> Result<()> {
85
5.67k
    assert!(max >= min);
86
5.67k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
5.67k
    for _ in 0..(max - min) {
92
5.67k
        let keep_going = u.arbitrary().unwrap_or(false);
93
5.67k
        if !keep_going {
94
4.23k
            break;
95
1.43k
        }
96
1.43k
97
1.43k
        if !f(u)? {
98
23
            break;
99
1.41k
        }
100
    }
101
102
5.67k
    Ok(())
103
5.67k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module19arbitrary_func_type0EB2_
Line
Count
Source
79
5.68k
pub(crate) fn arbitrary_loop<'a>(
80
5.68k
    u: &mut Unstructured<'a>,
81
5.68k
    min: usize,
82
5.68k
    max: usize,
83
5.68k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
5.68k
) -> Result<()> {
85
5.68k
    assert!(max >= min);
86
5.68k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
5.68k
    for _ in 0..(max - min) {
92
8.34k
        let keep_going = u.arbitrary().unwrap_or(false);
93
8.34k
        if !keep_going {
94
5.65k
            break;
95
2.68k
        }
96
2.68k
97
2.68k
        if !f(u)? {
98
0
            break;
99
2.68k
        }
100
    }
101
102
5.68k
    Ok(())
103
5.68k
}
_RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs3_NtB2_4coreNtBQ_6Module19arbitrary_func_types_0EB2_
Line
Count
Source
79
5.68k
pub(crate) fn arbitrary_loop<'a>(
80
5.68k
    u: &mut Unstructured<'a>,
81
5.68k
    min: usize,
82
5.68k
    max: usize,
83
5.68k
    mut f: impl FnMut(&mut Unstructured<'a>) -> Result<bool>,
84
5.68k
) -> Result<()> {
85
5.68k
    assert!(max >= min);
86
5.68k
    for _ in 0..min {
87
0
        if !f(u)? {
88
0
            return Err(arbitrary::Error::IncorrectFormat);
89
0
        }
90
    }
91
5.68k
    for _ in 0..(max - min) {
92
9.78k
        let keep_going = u.arbitrary().unwrap_or(false);
93
9.78k
        if !keep_going {
94
5.66k
            break;
95
4.12k
        }
96
4.12k
97
4.12k
        if !f(u)? {
98
0
            break;
99
4.12k
        }
100
    }
101
102
5.68k
    Ok(())
103
5.68k
}
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder19arbitrary_enum_type0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder19arbitrary_func_type0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder19arbitrary_func_types_0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder20arbitrary_flags_type0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder20arbitrary_tuple_type0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder21arbitrary_module_type0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder21arbitrary_record_type0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder22arbitrary_type_section0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder22arbitrary_variant_type0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder24arbitrary_import_section0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder27arbitrary_canonical_section0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvMs4_NtB2_9componentNtBQ_16ComponentBuilder27arbitrary_core_type_section0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvNtB2_9component19arbitrary_func_type0EB2_
Unexecuted instantiation: _RINvCs4eJdYXiOSk9_10wasm_smith14arbitrary_loopNCNvNtB2_9component19arbitrary_func_types_0EB2_
104
105
// Mirror what happens in `Arbitrary for String`, but do so with a clamped size.
106
14.1k
pub(crate) fn limited_str<'a>(max_size: usize, u: &mut Unstructured<'a>) -> Result<&'a str> {
107
14.1k
    let size = u.arbitrary_len::<u8>()?;
108
14.1k
    let size = std::cmp::min(size, max_size);
109
14.1k
    match str::from_utf8(u.peek_bytes(size).unwrap()) {
110
3.33k
        Ok(s) => {
111
3.33k
            u.bytes(size).unwrap();
112
3.33k
            Ok(s)
113
        }
114
10.7k
        Err(e) => {
115
10.7k
            let i = e.valid_up_to();
116
10.7k
            let valid = u.bytes(i).unwrap();
117
10.7k
            let s = str::from_utf8(valid).unwrap();
118
10.7k
            Ok(s)
119
        }
120
    }
121
14.1k
}
122
123
14.1k
pub(crate) fn limited_string(max_size: usize, u: &mut Unstructured) -> Result<String> {
124
14.1k
    Ok(limited_str(max_size, u)?.into())
125
14.1k
}
126
127
5.46k
pub(crate) fn unique_string(
128
5.46k
    max_size: usize,
129
5.46k
    names: &mut HashSet<String>,
130
5.46k
    u: &mut Unstructured,
131
5.46k
) -> Result<String> {
132
5.46k
    let mut name = limited_string(max_size, u)?;
133
9.61k
    while names.contains(&name) {
134
4.14k
        write!(&mut name, "{}", names.len()).unwrap();
135
4.14k
    }
136
5.46k
    names.insert(name.clone());
137
5.46k
    Ok(name)
138
5.46k
}
139
140
0
pub(crate) fn unique_kebab_string(
141
0
    max_size: usize,
142
0
    names: &mut HashSet<String>,
143
0
    u: &mut Unstructured,
144
0
) -> Result<String> {
145
0
    let size = std::cmp::min(u.arbitrary_len::<u8>()?, max_size);
146
0
    let mut name = String::with_capacity(size);
147
0
    let mut require_alpha = true;
148
0
    for _ in 0..size {
149
0
        name.push(match u.int_in_range::<u8>(0..=36)? {
150
0
            x if (0..26).contains(&x) => {
151
0
                require_alpha = false;
152
0
                (b'a' + x) as char
153
            }
154
0
            x if (26..36).contains(&x) => {
155
0
                if require_alpha {
156
0
                    require_alpha = false;
157
0
                    (b'a' + (x - 26)) as char
158
                } else {
159
0
                    (b'0' + (x - 26)) as char
160
                }
161
            }
162
0
            x if x == 36 => {
163
0
                if require_alpha {
164
0
                    require_alpha = false;
165
0
                    'a'
166
                } else {
167
0
                    require_alpha = true;
168
0
                    '-'
169
                }
170
            }
171
0
            _ => unreachable!(),
172
        });
173
    }
174
175
0
    if name.is_empty() || name.ends_with('-') {
176
0
        name.push('a');
177
0
    }
178
179
0
    while names.contains(&name) {
180
0
        write!(&mut name, "{}", names.len()).unwrap();
181
0
    }
182
183
0
    names.insert(name.clone());
184
0
185
0
    Ok(name)
186
0
}
187
188
0
pub(crate) fn unique_url(
189
0
    max_size: usize,
190
0
    names: &mut HashSet<String>,
191
0
    u: &mut Unstructured,
192
0
) -> Result<String> {
193
0
    let path = unique_kebab_string(max_size, names, u)?;
194
0
    Ok(format!("https://example.com/{path}"))
195
0
}
/Users/hota1024/GitHub/hota1024/wasmicon/crates/wasm_parser/src/decoder/binary/instructions/block.rs
Line
Count
Source (jump to first uncovered line)
1
use crate::decoder::binary::types::ValueType;
2
3
#[derive(Debug, Clone, PartialEq)]
4
pub struct Block {
5
    pub block_type: BlockType,
6
}
7
8
#[derive(Debug, Clone, PartialEq)]
9
pub enum BlockType {
10
    Empty,
11
    Value(Vec<ValueType>),
12
    TypeIndex(u32),
13
}
14
15
impl BlockType {
16
0
    pub fn result_count(&self) -> usize {
17
0
        match self {
18
0
            Self::Empty => 0,
19
0
            Self::Value(types) => types.len(),
20
0
            Self::TypeIndex(_) => 1,
21
        }
22
0
    }
23
}
/Users/hota1024/GitHub/hota1024/wasmicon/crates/wasm_parser/src/decoder/binary/module.rs
Line
Count
Source
1
use super::{
2
    section::Code,
3
    types::{Data, Element, Export, FuncType, Global, Import, MemoryType, TableType},
4
};
5
6
#[derive(Debug, Clone, PartialEq)]
7
pub struct Module {
8
    pub version: u32,
9
    pub custom_section: Option<()>,
10
    pub type_section: Option<Vec<FuncType>>,
11
    pub import_section: Option<Vec<Import>>,
12
    pub function_section: Option<Vec<u32>>,
13
    pub table_section: Option<Vec<TableType>>,
14
    pub memory_section: Option<Vec<MemoryType>>,
15
    pub global_section: Option<Vec<Global>>,
16
    pub export_section: Option<Vec<Export>>,
17
    pub start_section: Option<u32>,
18
    pub element_section: Option<Vec<Element>>,
19
    pub code_section: Option<Vec<Code>>,
20
    pub data_section: Option<Vec<Data>>,
21
    pub data_count_section: Option<u32>,
22
}
23
24
impl Default for Module {
25
5.67k
    fn default() -> Self {
26
5.67k
        Module {
27
5.67k
            version: 0,
28
5.67k
            custom_section: None,
29
5.67k
            type_section: None,
30
5.67k
            import_section: None,
31
5.67k
            function_section: None,
32
5.67k
            table_section: None,
33
5.67k
            memory_section: None,
34
5.67k
            global_section: None,
35
5.67k
            export_section: None,
36
5.67k
            start_section: None,
37
5.67k
            element_section: None,
38
5.67k
            code_section: None,
39
5.67k
            data_section: None,
40
5.67k
            data_count_section: None,
41
5.67k
        }
42
5.67k
    }
_RNvXNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary6moduleNtB2_6ModuleNtNtCs1ujR1JRCAmI_4core7default7Default7defaultCs5HNiFFfDLPG_6decode
Line
Count
Source
25
5.67k
    fn default() -> Self {
26
5.67k
        Module {
27
5.67k
            version: 0,
28
5.67k
            custom_section: None,
29
5.67k
            type_section: None,
30
5.67k
            import_section: None,
31
5.67k
            function_section: None,
32
5.67k
            table_section: None,
33
5.67k
            memory_section: None,
34
5.67k
            global_section: None,
35
5.67k
            export_section: None,
36
5.67k
            start_section: None,
37
5.67k
            element_section: None,
38
5.67k
            code_section: None,
39
5.67k
            data_section: None,
40
5.67k
            data_count_section: None,
41
5.67k
        }
42
5.67k
    }
Unexecuted instantiation: _RNvXNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary6moduleNtB2_6ModuleNtNtCs1ujR1JRCAmI_4core7default7Default7defaultB8_
43
}
/Users/hota1024/GitHub/hota1024/wasmicon/crates/wasm_parser/src/decoder/binary/section/id.rs
Line
Count
Source (jump to first uncovered line)
1
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
2
pub enum SectionId {
3
    Custom,
4
    Type,
5
    Import,
6
    Function,
7
    Table,
8
    Memory,
9
    Global,
10
    Export,
11
    Start,
12
    Element,
13
    Code,
14
    Data,
15
    DataCount,
16
    Unknown(u8),
17
}
18
19
impl From<u8> for SectionId {
20
21.4k
    fn from(value: u8) -> Self {
21
21.4k
        match value {
22
0
            0 => SectionId::Custom,
23
4.63k
            1 => SectionId::Type,
24
2.55k
            2 => SectionId::Import,
25
4.09k
            3 => SectionId::Function,
26
1.03k
            4 => SectionId::Table,
27
1.41k
            5 => SectionId::Memory,
28
1.67k
            6 => SectionId::Global,
29
897
            7 => SectionId::Export,
30
582
            8 => SectionId::Start,
31
252
            9 => SectionId::Element,
32
4.09k
            10 => SectionId::Code,
33
176
            11 => SectionId::Data,
34
0
            12 => SectionId::DataCount,
35
0
            _ => SectionId::Unknown(value),
36
        }
37
21.4k
    }
_RNvXNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary7section2idNtB2_9SectionIdINtNtCs1ujR1JRCAmI_4core7convert4FromhE4fromCs5HNiFFfDLPG_6decode
Line
Count
Source
20
21.4k
    fn from(value: u8) -> Self {
21
21.4k
        match value {
22
0
            0 => SectionId::Custom,
23
4.63k
            1 => SectionId::Type,
24
2.55k
            2 => SectionId::Import,
25
4.09k
            3 => SectionId::Function,
26
1.03k
            4 => SectionId::Table,
27
1.41k
            5 => SectionId::Memory,
28
1.67k
            6 => SectionId::Global,
29
897
            7 => SectionId::Export,
30
582
            8 => SectionId::Start,
31
252
            9 => SectionId::Element,
32
4.09k
            10 => SectionId::Code,
33
176
            11 => SectionId::Data,
34
0
            12 => SectionId::DataCount,
35
0
            _ => SectionId::Unknown(value),
36
        }
37
21.4k
    }
Unexecuted instantiation: _RNvXNtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary7section2idNtB2_9SectionIdINtNtCs1ujR1JRCAmI_4core7convert4FromhE4fromBa_
38
}
39
40
impl SectionId {
41
21.4k
    pub fn is_unknown(&self) -> bool {
42
21.4k
        match self {
43
0
            SectionId::Unknown(_) => true,
44
21.4k
            _ => false,
45
        }
46
21.4k
    }
_RNvMs_NtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary7section2idNtB4_9SectionId10is_unknownCs5HNiFFfDLPG_6decode
Line
Count
Source
41
21.4k
    pub fn is_unknown(&self) -> bool {
42
21.4k
        match self {
43
0
            SectionId::Unknown(_) => true,
44
21.4k
            _ => false,
45
        }
46
21.4k
    }
Unexecuted instantiation: _RNvMs_NtNtNtNtCsatfCxygFw5y_11wasm_parser7decoder6binary7section2idNtB4_9SectionId10is_unknownBc_
47
}
/Users/hota1024/GitHub/hota1024/wasmicon/crates/wasm_parser/src/decoder/decoder.rs
Line
Count
Source (jump to first uncovered line)
1
use anyhow::{bail, Context};
2
use std::io::{BufReader, Read};
3
4
use crate::decoder::binary::types::ValueType;
5
6
use super::{
7
    binary::{
8
        instructions::{Block, BlockType, Instruction, MemArg},
9
        module::Module,
10
        section::{Code, SectionId},
11
        types::{
12
            Element, ElementMode, Export, ExportDesc, FuncType, Global, GlobalType, Import,
13
            ImportDesc, Limits, MemoryType, RefType, TableType,
14
        },
15
    },
16
    result::{DecodeError, Result},
17
    types::{Data, DataMode},
18
};
19
20
pub struct Decoder<R> {
21
    reader: BufReader<R>,
22
}
23
24
impl<R: Read> Decoder<R> {
25
21.4k
    pub fn new(reader: R) -> Self {
26
21.4k
        Decoder {
27
21.4k
            reader: BufReader::new(reader),
28
21.4k
        }
29
21.4k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE3newCs5HNiFFfDLPG_6decode
Line
Count
Source
25
21.4k
    pub fn new(reader: R) -> Self {
26
21.4k
        Decoder {
27
21.4k
            reader: BufReader::new(reader),
28
21.4k
        }
29
21.4k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE3newB6_
30
31
168k
    fn is_empty(&mut self) -> bool {
32
168k
        // self.reader.fill_buf().unwrap().is_empty()
33
168k
        self.reader.buffer().is_empty()
34
168k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE8is_emptyCs5HNiFFfDLPG_6decode
Line
Count
Source
31
168k
    fn is_empty(&mut self) -> bool {
32
168k
        // self.reader.fill_buf().unwrap().is_empty()
33
168k
        self.reader.buffer().is_empty()
34
168k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE8is_emptyB6_
35
36
5.67k
    pub fn decode(&mut self) -> Result<Module> {
37
5.67k
        self.validate_magic_header()?;
38
5.67k
        let version = self.decode_version()?;
39
40
5.67k
        if version != 1 {
41
0
            bail!(DecodeError::InvalidVersion);
42
5.67k
        }
43
5.67k
44
5.67k
        let mut module = Module::default();
45
46
27.0k
        loop {
47
27.0k
            if self.is_empty() {
48
5.67k
                break;
49
21.4k
            }
50
51
21.4k
            let id = match self.read_section() {
52
21.4k
                Ok((id, _)) => id,
53
0
                Err(e) => return Err(e),
54
            };
55
56
21.4k
            match id {
57
0
                SectionId::Custom => {}
58
4.63k
                SectionId::Type => {
59
4.63k
                    module.type_section =
60
4.63k
                        Some(self.decode_type_section().context("decode type section")?);
61
                }
62
2.55k
                SectionId::Import => {
63
2.55k
                    module.import_section = Some(
64
2.55k
                        self.decode_import_section()
65
2.55k
                            .context("decode import section")?,
66
                    );
67
                }
68
4.09k
                SectionId::Function => {
69
4.09k
                    module.function_section = Some(
70
4.09k
                        self.decode_function_section()
71
4.09k
                            .context("decode function section")?,
72
                    );
73
                }
74
1.03k
                SectionId::Table => {
75
1.03k
                    module.table_section = Some(
76
1.03k
                        self.decode_table_section()
77
1.03k
                            .context("decode table section")?,
78
                    );
79
                }
80
1.41k
                SectionId::Memory => {
81
1.41k
                    module.memory_section = Some(
82
1.41k
                        self.decode_memory_section()
83
1.41k
                            .context("decode memory section")?,
84
                    );
85
                }
86
1.67k
                SectionId::Global => {
87
1.67k
                    module.global_section = Some(
88
1.67k
                        self.decode_global_section()
89
1.67k
                            .context("decode global section")?,
90
                    );
91
                }
92
897
                SectionId::Export => {
93
897
                    module.export_section = Some(
94
897
                        self.decode_export_section()
95
897
                            .context("decode export section")?,
96
                    );
97
                }
98
                SectionId::Start => {
99
582
                    module.start_section = self
100
582
                        .decode_start_section()
101
582
                        .context("decode start section")?;
102
                }
103
252
                SectionId::Element => {
104
252
                    module.element_section = Some(
105
252
                        self.decode_element_section()
106
252
                            .context("decode element section")?,
107
                    );
108
                }
109
4.09k
                SectionId::Code => {
110
4.09k
                    module.code_section =
111
4.09k
                        Some(self.decode_code_section().context("decode code section")?);
112
                }
113
176
                SectionId::Data => {
114
176
                    module.data_section =
115
176
                        Some(self.decode_data_section().context("decode data section")?);
116
                }
117
                SectionId::DataCount => {
118
                    module.data_count_section = Some(
119
0
                        self.decode_data_count_section()
120
0
                            .context("decode data count section")?,
121
                    );
122
                }
123
                _ => {
124
0
                    unimplemented!("[decode] {:?} is not implemented", id)
125
                }
126
            }
127
        }
128
129
5.67k
        Ok(module)
130
5.67k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE6decodeCs5HNiFFfDLPG_6decode
Line
Count
Source
36
5.67k
    pub fn decode(&mut self) -> Result<Module> {
37
5.67k
        self.validate_magic_header()?;
38
5.67k
        let version = self.decode_version()?;
39
40
5.67k
        if version != 1 {
41
0
            bail!(DecodeError::InvalidVersion);
42
5.67k
        }
43
5.67k
44
5.67k
        let mut module = Module::default();
45
46
27.0k
        loop {
47
27.0k
            if self.is_empty() {
48
5.67k
                break;
49
21.4k
            }
50
51
21.4k
            let id = match self.read_section() {
52
21.4k
                Ok((id, _)) => id,
53
0
                Err(e) => return Err(e),
54
            };
55
56
21.4k
            match id {
57
0
                SectionId::Custom => {}
58
4.63k
                SectionId::Type => {
59
4.63k
                    module.type_section =
60
4.63k
                        Some(self.decode_type_section().context("decode type section")?);
61
                }
62
2.55k
                SectionId::Import => {
63
2.55k
                    module.import_section = Some(
64
2.55k
                        self.decode_import_section()
65
2.55k
                            .context("decode import section")?,
66
                    );
67
                }
68
4.09k
                SectionId::Function => {
69
4.09k
                    module.function_section = Some(
70
4.09k
                        self.decode_function_section()
71
4.09k
                            .context("decode function section")?,
72
                    );
73
                }
74
1.03k
                SectionId::Table => {
75
1.03k
                    module.table_section = Some(
76
1.03k
                        self.decode_table_section()
77
1.03k
                            .context("decode table section")?,
78
                    );
79
                }
80
1.41k
                SectionId::Memory => {
81
1.41k
                    module.memory_section = Some(
82
1.41k
                        self.decode_memory_section()
83
1.41k
                            .context("decode memory section")?,
84
                    );
85
                }
86
1.67k
                SectionId::Global => {
87
1.67k
                    module.global_section = Some(
88
1.67k
                        self.decode_global_section()
89
1.67k
                            .context("decode global section")?,
90
                    );
91
                }
92
897
                SectionId::Export => {
93
897
                    module.export_section = Some(
94
897
                        self.decode_export_section()
95
897
                            .context("decode export section")?,
96
                    );
97
                }
98
                SectionId::Start => {
99
582
                    module.start_section = self
100
582
                        .decode_start_section()
101
582
                        .context("decode start section")?;
102
                }
103
252
                SectionId::Element => {
104
252
                    module.element_section = Some(
105
252
                        self.decode_element_section()
106
252
                            .context("decode element section")?,
107
                    );
108
                }
109
4.09k
                SectionId::Code => {
110
4.09k
                    module.code_section =
111
4.09k
                        Some(self.decode_code_section().context("decode code section")?);
112
                }
113
176
                SectionId::Data => {
114
176
                    module.data_section =
115
176
                        Some(self.decode_data_section().context("decode data section")?);
116
                }
117
                SectionId::DataCount => {
118
                    module.data_count_section = Some(
119
0
                        self.decode_data_count_section()
120
0
                            .context("decode data count section")?,
121
                    );
122
                }
123
                _ => {
124
0
                    unimplemented!("[decode] {:?} is not implemented", id)
125
                }
126
            }
127
        }
128
129
5.67k
        Ok(module)
130
5.67k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE6decodeB6_
131
132
5.67k
    fn validate_magic_header(&mut self) -> Result<()> {
133
5.67k
        let mut magic = [0; 4];
134
5.67k
        self.reader.read_exact(&mut magic).unwrap();
135
5.67k
136
5.67k
        match magic {
137
5.67k
            [0x00, 0x61, 0x73, 0x6d] => Ok(()),
138
0
            _ => bail!(DecodeError::InvalidMagicHeader),
139
        }
140
5.67k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE21validate_magic_headerCs5HNiFFfDLPG_6decode
Line
Count
Source
132
5.67k
    fn validate_magic_header(&mut self) -> Result<()> {
133
5.67k
        let mut magic = [0; 4];
134
5.67k
        self.reader.read_exact(&mut magic).unwrap();
135
5.67k
136
5.67k
        match magic {
137
5.67k
            [0x00, 0x61, 0x73, 0x6d] => Ok(()),
138
0
            _ => bail!(DecodeError::InvalidMagicHeader),
139
        }
140
5.67k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE21validate_magic_headerB6_
141
142
5.67k
    fn decode_version(&mut self) -> Result<u32> {
143
5.67k
        let mut version = [0; 4];
144
5.67k
        self.reader.read_exact(&mut version).unwrap();
145
5.67k
146
5.67k
        Ok(u32::from_le_bytes(version))
147
5.67k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE14decode_versionCs5HNiFFfDLPG_6decode
Line
Count
Source
142
5.67k
    fn decode_version(&mut self) -> Result<u32> {
143
5.67k
        let mut version = [0; 4];
144
5.67k
        self.reader.read_exact(&mut version).unwrap();
145
5.67k
146
5.67k
        Ok(u32::from_le_bytes(version))
147
5.67k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE14decode_versionB6_
148
149
4.63k
    fn decode_type_section(&mut self) -> Result<Vec<FuncType>> {
150
5.68k
        self.read_vec(|d| {
151
5.68k
            let kind = d.read_u8()?;
152
153
            // functype starts with `0x60`.
154
            // Ref: https://webassembly.github.io/spec/core/binary/types.html#function-types
155
5.68k
            if kind != 0x60 {
156
0
                bail!(DecodeError::InvalidTypeKind);
157
5.68k
            }
158
159
5.68k
            let params = d.read_vec(|d| d.read_value_type()).context("read params")?;
_RNCNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB6_7DecoderRShE19decode_type_section00Cs5HNiFFfDLPG_6decode
Line
Count
Source
159
2.68k
            let params = d.read_vec(|d| d.read_value_type()).context("read params")?;
Unexecuted instantiation: _RNCNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB6_7DecoderpE19decode_type_section00Ba_
160
161
5.68k
            let results = d
162
5.68k
                .read_vec(|d| d.read_value_type())
_RNCNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB6_7DecoderRShE19decode_type_section0s_0Cs5HNiFFfDLPG_6decode
Line
Count
Source
162
4.12k
                .read_vec(|d| d.read_value_type())
Unexecuted instantiation: _RNCNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB6_7DecoderpE19decode_type_section0s_0Ba_
163
5.68k
                .context("read results")?;
164
165
5.68k
            Ok(FuncType { params, results })
166
5.68k
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE19decode_type_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
150
5.68k
        self.read_vec(|d| {
151
5.68k
            let kind = d.read_u8()?;
152
153
            // functype starts with `0x60`.
154
            // Ref: https://webassembly.github.io/spec/core/binary/types.html#function-types
155
5.68k
            if kind != 0x60 {
156
0
                bail!(DecodeError::InvalidTypeKind);
157
5.68k
            }
158
159
5.68k
            let params = d.read_vec(|d| d.read_value_type()).context("read params")?;
160
161
5.68k
            let results = d
162
5.68k
                .read_vec(|d| d.read_value_type())
163
5.68k
                .context("read results")?;
164
165
5.68k
            Ok(FuncType { params, results })
166
5.68k
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE19decode_type_section0B8_
167
4.63k
        .context("read type section vector")
168
4.63k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE19decode_type_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
149
4.63k
    fn decode_type_section(&mut self) -> Result<Vec<FuncType>> {
150
4.63k
        self.read_vec(|d| {
151
            let kind = d.read_u8()?;
152
153
            // functype starts with `0x60`.
154
            // Ref: https://webassembly.github.io/spec/core/binary/types.html#function-types
155
            if kind != 0x60 {
156
                bail!(DecodeError::InvalidTypeKind);
157
            }
158
159
            let params = d.read_vec(|d| d.read_value_type()).context("read params")?;
160
161
            let results = d
162
                .read_vec(|d| d.read_value_type())
163
                .context("read results")?;
164
165
            Ok(FuncType { params, results })
166
4.63k
        })
167
4.63k
        .context("read type section vector")
168
4.63k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE19decode_type_sectionB6_
169
170
2.55k
    fn decode_import_section(&mut self) -> Result<Vec<Import>> {
171
4.32k
        self.read_vec(|d| {
172
4.32k
            let module = d.read_name()?;
173
4.32k
            let field = d.read_name()?;
174
4.32k
            let desc_id = d.read_u8()?;
175
176
4.32k
            let desc = match desc_id {
177
                0x00 => {
178
1.56k
                    let type_index = d.read_size()?;
179
1.56k
                    ImportDesc::Func(type_index)
180
                }
181
                0x01 => {
182
288
                    let type_index = d.read_table_type()?;
183
288
                    ImportDesc::Table(type_index)
184
                }
185
                0x02 => {
186
336
                    let limits = d.read_limits()?;
187
336
                    ImportDesc::Memory(limits)
188
                }
189
                0x03 => {
190
2.13k
                    let global = d.read_global_type()?;
191
2.13k
                    ImportDesc::Global(global)
192
                }
193
0
                id => bail!(DecodeError::InvalidImportDescription(id)),
194
            };
195
196
4.32k
            Ok(Import {
197
4.32k
                module,
198
4.32k
                field,
199
4.32k
                desc,
200
4.32k
            })
201
4.32k
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE21decode_import_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
171
4.32k
        self.read_vec(|d| {
172
4.32k
            let module = d.read_name()?;
173
4.32k
            let field = d.read_name()?;
174
4.32k
            let desc_id = d.read_u8()?;
175
176
4.32k
            let desc = match desc_id {
177
                0x00 => {
178
1.56k
                    let type_index = d.read_size()?;
179
1.56k
                    ImportDesc::Func(type_index)
180
                }
181
                0x01 => {
182
288
                    let type_index = d.read_table_type()?;
183
288
                    ImportDesc::Table(type_index)
184
                }
185
                0x02 => {
186
336
                    let limits = d.read_limits()?;
187
336
                    ImportDesc::Memory(limits)
188
                }
189
                0x03 => {
190
2.13k
                    let global = d.read_global_type()?;
191
2.13k
                    ImportDesc::Global(global)
192
                }
193
0
                id => bail!(DecodeError::InvalidImportDescription(id)),
194
            };
195
196
4.32k
            Ok(Import {
197
4.32k
                module,
198
4.32k
                field,
199
4.32k
                desc,
200
4.32k
            })
201
4.32k
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE21decode_import_section0B8_
202
2.55k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE21decode_import_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
170
2.55k
    fn decode_import_section(&mut self) -> Result<Vec<Import>> {
171
2.55k
        self.read_vec(|d| {
172
            let module = d.read_name()?;
173
            let field = d.read_name()?;
174
            let desc_id = d.read_u8()?;
175
176
            let desc = match desc_id {
177
                0x00 => {
178
                    let type_index = d.read_size()?;
179
                    ImportDesc::Func(type_index)
180
                }
181
                0x01 => {
182
                    let type_index = d.read_table_type()?;
183
                    ImportDesc::Table(type_index)
184
                }
185
                0x02 => {
186
                    let limits = d.read_limits()?;
187
                    ImportDesc::Memory(limits)
188
                }
189
                0x03 => {
190
                    let global = d.read_global_type()?;
191
                    ImportDesc::Global(global)
192
                }
193
                id => bail!(DecodeError::InvalidImportDescription(id)),
194
            };
195
196
            Ok(Import {
197
                module,
198
                field,
199
                desc,
200
            })
201
2.55k
        })
202
2.55k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE21decode_import_sectionB6_
203
204
4.09k
    fn decode_function_section(&mut self) -> Result<Vec<u32>> {
205
15.8k
        self.read_vec(|d| d.read_size())
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE23decode_function_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
205
15.8k
        self.read_vec(|d| d.read_size())
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE23decode_function_section0B8_
206
4.09k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE23decode_function_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
204
4.09k
    fn decode_function_section(&mut self) -> Result<Vec<u32>> {
205
4.09k
        self.read_vec(|d| d.read_size())
206
4.09k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE23decode_function_sectionB6_
207
208
1.03k
    fn decode_table_section(&mut self) -> Result<Vec<TableType>> {
209
1.03k
        self.read_vec(|d| {
210
1.03k
            Ok(TableType {
211
1.03k
                element_type: d.read_reference_type()?,
212
1.03k
                limits: d.read_limits()?,
213
            })
214
1.03k
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE20decode_table_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
209
1.03k
        self.read_vec(|d| {
210
1.03k
            Ok(TableType {
211
1.03k
                element_type: d.read_reference_type()?,
212
1.03k
                limits: d.read_limits()?,
213
            })
214
1.03k
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE20decode_table_section0B8_
215
1.03k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE20decode_table_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
208
1.03k
    fn decode_table_section(&mut self) -> Result<Vec<TableType>> {
209
1.03k
        self.read_vec(|d| {
210
            Ok(TableType {
211
                element_type: d.read_reference_type()?,
212
                limits: d.read_limits()?,
213
            })
214
1.03k
        })
215
1.03k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE20decode_table_sectionB6_
216
217
1.41k
    fn decode_memory_section(&mut self) -> Result<Vec<MemoryType>> {
218
1.41k
        self.read_vec(|d| {
219
1.41k
            Ok(MemoryType {
220
1.41k
                limits: d.read_limits()?,
221
            })
222
1.41k
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE21decode_memory_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
218
1.41k
        self.read_vec(|d| {
219
1.41k
            Ok(MemoryType {
220
1.41k
                limits: d.read_limits()?,
221
            })
222
1.41k
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE21decode_memory_section0B8_
223
1.41k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE21decode_memory_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
217
1.41k
    fn decode_memory_section(&mut self) -> Result<Vec<MemoryType>> {
218
1.41k
        self.read_vec(|d| {
219
            Ok(MemoryType {
220
                limits: d.read_limits()?,
221
            })
222
1.41k
        })
223
1.41k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE21decode_memory_sectionB6_
224
225
1.67k
    fn decode_global_section(&mut self) -> Result<Vec<Global>> {
226
3.51k
        self.read_vec(|d| {
227
3.51k
            let value_type = d.read_value_type()?;
228
3.51k
            let mutable = d.read_u8()? == 0x01;
229
230
3.51k
            let init_expr = d.read_instruction_and_end()?;
231
232
3.51k
            Ok(Global {
233
3.51k
                global_type: GlobalType {
234
3.51k
                    value_type,
235
3.51k
                    mutable,
236
3.51k
                },
237
3.51k
                init_expr,
238
3.51k
            })
239
3.51k
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE21decode_global_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
226
3.51k
        self.read_vec(|d| {
227
3.51k
            let value_type = d.read_value_type()?;
228
3.51k
            let mutable = d.read_u8()? == 0x01;
229
230
3.51k
            let init_expr = d.read_instruction_and_end()?;
231
232
3.51k
            Ok(Global {
233
3.51k
                global_type: GlobalType {
234
3.51k
                    value_type,
235
3.51k
                    mutable,
236
3.51k
                },
237
3.51k
                init_expr,
238
3.51k
            })
239
3.51k
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE21decode_global_section0B8_
240
1.67k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE21decode_global_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
225
1.67k
    fn decode_global_section(&mut self) -> Result<Vec<Global>> {
226
1.67k
        self.read_vec(|d| {
227
            let value_type = d.read_value_type()?;
228
            let mutable = d.read_u8()? == 0x01;
229
230
            let init_expr = d.read_instruction_and_end()?;
231
232
            Ok(Global {
233
                global_type: GlobalType {
234
                    value_type,
235
                    mutable,
236
                },
237
                init_expr,
238
            })
239
1.67k
        })
240
1.67k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE21decode_global_sectionB6_
241
242
897
    fn decode_export_section(&mut self) -> Result<Vec<Export>> {
243
5.46k
        self.read_vec(|d| {
244
5.46k
            let name = d.read_name()?;
245
5.46k
            let desc_kind = d.read_u8()?;
246
247
5.46k
            let desc = match desc_kind {
248
2.28k
                0x00 => ExportDesc::Func(d.read_size()?),
249
926
                0x01 => ExportDesc::Table(d.read_size()?),
250
1.23k
                0x02 => ExportDesc::Mem(d.read_size()?),
251
1.02k
                0x03 => ExportDesc::Global(d.read_size()?),
252
0
                _ => bail!(DecodeError::InvalidExportDescription),
253
            };
254
255
5.46k
            Ok(Export { name, desc })
256
5.46k
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE21decode_export_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
243
5.46k
        self.read_vec(|d| {
244
5.46k
            let name = d.read_name()?;
245
5.46k
            let desc_kind = d.read_u8()?;
246
247
5.46k
            let desc = match desc_kind {
248
2.28k
                0x00 => ExportDesc::Func(d.read_size()?),
249
926
                0x01 => ExportDesc::Table(d.read_size()?),
250
1.23k
                0x02 => ExportDesc::Mem(d.read_size()?),
251
1.02k
                0x03 => ExportDesc::Global(d.read_size()?),
252
0
                _ => bail!(DecodeError::InvalidExportDescription),
253
            };
254
255
5.46k
            Ok(Export { name, desc })
256
5.46k
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE21decode_export_section0B8_
257
897
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE21decode_export_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
242
897
    fn decode_export_section(&mut self) -> Result<Vec<Export>> {
243
897
        self.read_vec(|d| {
244
            let name = d.read_name()?;
245
            let desc_kind = d.read_u8()?;
246
247
            let desc = match desc_kind {
248
                0x00 => ExportDesc::Func(d.read_size()?),
249
                0x01 => ExportDesc::Table(d.read_size()?),
250
                0x02 => ExportDesc::Mem(d.read_size()?),
251
                0x03 => ExportDesc::Global(d.read_size()?),
252
                _ => bail!(DecodeError::InvalidExportDescription),
253
            };
254
255
            Ok(Export { name, desc })
256
897
        })
257
897
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE21decode_export_sectionB6_
258
259
582
    fn decode_start_section(&mut self) -> Result<Option<u32>> {
260
582
        let index = self.read_size()?;
261
582
        Ok(Some(index))
262
582
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE20decode_start_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
259
582
    fn decode_start_section(&mut self) -> Result<Option<u32>> {
260
582
        let index = self.read_size()?;
261
582
        Ok(Some(index))
262
582
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE20decode_start_sectionB6_
263
264
252
    fn decode_element_section(&mut self) -> Result<Vec<Element>> {
265
1.58k
        self.read_vec(|d| {
266
1.58k
            let prefix = d.read_size()?;
267
268
1.58k
            let element = match prefix {
269
                0 => {
270
1.58k
                    let offset = d.read_instruction_and_end()?;
271
2.41k
                    let init = d.read_vec(|d| d.read_size())?;
_RNCNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB6_7DecoderRShE22decode_element_section00Cs5HNiFFfDLPG_6decode
Line
Count
Source
271
2.41k
                    let init = d.read_vec(|d| d.read_size())?;
Unexecuted instantiation: _RNCNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB6_7DecoderpE22decode_element_section00Ba_
272
273
1.58k
                    Element {
274
1.58k
                        ref_type: RefType::FuncRef,
275
1.58k
                        init,
276
1.58k
                        mode: ElementMode::Active {
277
1.58k
                            table_index: 0,
278
1.58k
                            offset,
279
1.58k
                        },
280
1.58k
                    }
281
                }
282
0
                _ => bail!(DecodeError::UnsupportedElementPrefix),
283
            };
284
285
1.58k
            Ok(element)
286
1.58k
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE22decode_element_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
265
1.58k
        self.read_vec(|d| {
266
1.58k
            let prefix = d.read_size()?;
267
268
1.58k
            let element = match prefix {
269
                0 => {
270
1.58k
                    let offset = d.read_instruction_and_end()?;
271
1.58k
                    let init = d.read_vec(|d| d.read_size())?;
272
273
1.58k
                    Element {
274
1.58k
                        ref_type: RefType::FuncRef,
275
1.58k
                        init,
276
1.58k
                        mode: ElementMode::Active {
277
1.58k
                            table_index: 0,
278
1.58k
                            offset,
279
1.58k
                        },
280
1.58k
                    }
281
                }
282
0
                _ => bail!(DecodeError::UnsupportedElementPrefix),
283
            };
284
285
1.58k
            Ok(element)
286
1.58k
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE22decode_element_section0B8_
287
252
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE22decode_element_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
264
252
    fn decode_element_section(&mut self) -> Result<Vec<Element>> {
265
252
        self.read_vec(|d| {
266
            let prefix = d.read_size()?;
267
268
            let element = match prefix {
269
                0 => {
270
                    let offset = d.read_instruction_and_end()?;
271
                    let init = d.read_vec(|d| d.read_size())?;
272
273
                    Element {
274
                        ref_type: RefType::FuncRef,
275
                        init,
276
                        mode: ElementMode::Active {
277
                            table_index: 0,
278
                            offset,
279
                        },
280
                    }
281
                }
282
                _ => bail!(DecodeError::UnsupportedElementPrefix),
283
            };
284
285
            Ok(element)
286
252
        })
287
252
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE22decode_element_sectionB6_
288
289
4.09k
    fn decode_code_section(&mut self) -> Result<Vec<Code>> {
290
15.8k
        self.read_vec(|d| {
291
15.8k
            let body_size = d.read_size()?;
292
15.8k
            let bytes = d.read_bytes(body_size as usize)?;
293
15.8k
            let mut d = Decoder::new(bytes.as_slice());
294
295
15.8k
            let locals: Vec<ValueType> = d
296
15.8k
                .read_vec(|d| {
297
3.10k
                    let mut locals = vec![];
298
3.10k
                    let local_count = d.read_size()?;
299
3.10k
                    let ty = d.read_value_type()?;
300
301
3.10k
                    for _ in 0..local_count {
302
3.10k
                        locals.push(ty.clone());
303
3.10k
                    }
304
305
3.10k
                    Ok(locals)
306
15.8k
                })?
_RNCNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB6_7DecoderRShE19decode_code_section00Cs5HNiFFfDLPG_6decode
Line
Count
Source
296
3.10k
                .read_vec(|d| {
297
3.10k
                    let mut locals = vec![];
298
3.10k
                    let local_count = d.read_size()?;
299
3.10k
                    let ty = d.read_value_type()?;
300
301
3.10k
                    for _ in 0..local_count {
302
3.10k
                        locals.push(ty.clone());
303
3.10k
                    }
304
305
3.10k
                    Ok(locals)
306
3.10k
                })?
Unexecuted instantiation: _RNCNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB6_7DecoderpE19decode_code_section00Ba_
307
15.8k
                .into_iter()
308
15.8k
                .flatten()
309
15.8k
                .collect();
310
311
15.8k
            let body = d.read_instructions()?;
312
313
15.8k
            Ok(Code { locals, code: body })
314
15.8k
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE19decode_code_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
290
15.8k
        self.read_vec(|d| {
291
15.8k
            let body_size = d.read_size()?;
292
15.8k
            let bytes = d.read_bytes(body_size as usize)?;
293
15.8k
            let mut d = Decoder::new(bytes.as_slice());
294
295
15.8k
            let locals: Vec<ValueType> = d
296
15.8k
                .read_vec(|d| {
297
                    let mut locals = vec![];
298
                    let local_count = d.read_size()?;
299
                    let ty = d.read_value_type()?;
300
301
                    for _ in 0..local_count {
302
                        locals.push(ty.clone());
303
                    }
304
305
                    Ok(locals)
306
15.8k
                })?
307
15.8k
                .into_iter()
308
15.8k
                .flatten()
309
15.8k
                .collect();
310
311
15.8k
            let body = d.read_instructions()?;
312
313
15.8k
            Ok(Code { locals, code: body })
314
15.8k
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE19decode_code_section0B8_
315
4.09k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE19decode_code_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
289
4.09k
    fn decode_code_section(&mut self) -> Result<Vec<Code>> {
290
4.09k
        self.read_vec(|d| {
291
            let body_size = d.read_size()?;
292
            let bytes = d.read_bytes(body_size as usize)?;
293
            let mut d = Decoder::new(bytes.as_slice());
294
295
            let locals: Vec<ValueType> = d
296
                .read_vec(|d| {
297
                    let mut locals = vec![];
298
                    let local_count = d.read_size()?;
299
                    let ty = d.read_value_type()?;
300
301
                    for _ in 0..local_count {
302
                        locals.push(ty.clone());
303
                    }
304
305
                    Ok(locals)
306
                })?
307
                .into_iter()
308
                .flatten()
309
                .collect();
310
311
            let body = d.read_instructions()?;
312
313
            Ok(Code { locals, code: body })
314
4.09k
        })
315
4.09k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE19decode_code_sectionB6_
316
317
176
    fn decode_data_section(&mut self) -> Result<Vec<Data>> {
318
776
        self.read_vec(|d| {
319
776
            let prefix = d.read_size()?;
320
321
776
            let data = match prefix {
322
                0 => {
323
776
                    let expr = d.read_instruction_and_end()?;
324
776
                    let size = d.read_size()?;
325
776
                    let bytes = d.read_bytes(size as usize)?;
326
327
776
                    Data {
328
776
                        bytes,
329
776
                        mode: DataMode::Active {
330
776
                            memory_index: 0,
331
776
                            offset: expr,
332
776
                        },
333
776
                    }
334
                }
335
0
                p => bail!(DecodeError::UnsupportedDataPrefix(p)),
336
            };
337
338
776
            Ok(data)
339
776
        })
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE19decode_data_section0Cs5HNiFFfDLPG_6decode
Line
Count
Source
318
776
        self.read_vec(|d| {
319
776
            let prefix = d.read_size()?;
320
321
776
            let data = match prefix {
322
                0 => {
323
776
                    let expr = d.read_instruction_and_end()?;
324
776
                    let size = d.read_size()?;
325
776
                    let bytes = d.read_bytes(size as usize)?;
326
327
776
                    Data {
328
776
                        bytes,
329
776
                        mode: DataMode::Active {
330
776
                            memory_index: 0,
331
776
                            offset: expr,
332
776
                        },
333
776
                    }
334
                }
335
0
                p => bail!(DecodeError::UnsupportedDataPrefix(p)),
336
            };
337
338
776
            Ok(data)
339
776
        })
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE19decode_data_section0B8_
340
176
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE19decode_data_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
317
176
    fn decode_data_section(&mut self) -> Result<Vec<Data>> {
318
176
        self.read_vec(|d| {
319
            let prefix = d.read_size()?;
320
321
            let data = match prefix {
322
                0 => {
323
                    let expr = d.read_instruction_and_end()?;
324
                    let size = d.read_size()?;
325
                    let bytes = d.read_bytes(size as usize)?;
326
327
                    Data {
328
                        bytes,
329
                        mode: DataMode::Active {
330
                            memory_index: 0,
331
                            offset: expr,
332
                        },
333
                    }
334
                }
335
                p => bail!(DecodeError::UnsupportedDataPrefix(p)),
336
            };
337
338
            Ok(data)
339
176
        })
340
176
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE19decode_data_sectionB6_
341
342
0
    fn decode_data_count_section(&mut self) -> Result<u32> {
343
0
        self.read_size()
344
0
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE25decode_data_count_sectionCs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE25decode_data_count_sectionB6_
345
346
15.8k
    fn read_instructions(&mut self) -> Result<Vec<Instruction>> {
347
15.8k
        let mut instructions = Vec::new();
348
349
        loop {
350
141k
            if self.is_empty() {
351
15.8k
                break;
352
125k
            }
353
354
125k
            let instr = self.read_instruction()?;
355
356
125k
            instructions.push(instr);
357
        }
358
359
15.8k
        Ok(instructions)
360
15.8k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE17read_instructionsCs5HNiFFfDLPG_6decode
Line
Count
Source
346
15.8k
    fn read_instructions(&mut self) -> Result<Vec<Instruction>> {
347
15.8k
        let mut instructions = Vec::new();
348
349
        loop {
350
141k
            if self.is_empty() {
351
15.8k
                break;
352
125k
            }
353
354
125k
            let instr = self.read_instruction()?;
355
356
125k
            instructions.push(instr);
357
        }
358
359
15.8k
        Ok(instructions)
360
15.8k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE17read_instructionsB6_
361
362
131k
    fn read_instruction(&mut self) -> Result<Instruction> {
363
131k
        let opcode = match self.read_u8() {
364
131k
            Ok(opcode) => opcode,
365
0
            Err(err) => {
366
0
                return Err(err);
367
            }
368
        };
369
370
131k
        let instr = match opcode {
371
            // control instructions
372
9.90k
            0x00 => Instruction::Unreachable,
373
1.70k
            0x01 => Instruction::Nop,
374
            0x02 => Instruction::Block {
375
                block: Block {
376
4.04k
                    block_type: self.read_block_type().context("instruction block")?,
377
                },
378
            },
379
            0x03 => Instruction::Loop {
380
                block: Block {
381
2.22k
                    block_type: self.read_block_type().context("instruction loop block")?,
382
                },
383
            },
384
            0x04 => Instruction::If {
385
                block: Block {
386
411
                    block_type: self.read_block_type().context("instruction if block")?,
387
                },
388
            },
389
288
            0x05 => Instruction::Else,
390
22.4k
            0x0B => Instruction::End,
391
            0x0C => Instruction::Br {
392
2.53k
                level: self.read_size()?,
393
            },
394
            0x0D => Instruction::BrIf {
395
556
                level: self.read_size()?,
396
            },
397
            0xE => Instruction::BrTable {
398
2.47k
                label_indexes: self.read_vec(|d| d.read_size())?,
_RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE16read_instruction0Cs5HNiFFfDLPG_6decode
Line
Count
Source
398
2.47k
                label_indexes: self.read_vec(|d| d.read_size())?,
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE16read_instruction0B8_
399
726
                default_index: self.read_size()?,
400
            },
401
465
            0x0F => Instruction::Return,
402
            0x10 => Instruction::Call {
403
4.35k
                func_index: self.read_size()?,
404
            },
405
            0x11 => Instruction::CallIndirect {
406
461
                type_index: self.read_size()?,
407
461
                table_index: self.read_size()?,
408
            },
409
            // reference instructions
410
            0xD0 => Instruction::RefNull {
411
0
                ref_type: self.read_reference_type()?,
412
            },
413
0
            0xD1 => Instruction::RefIsNull,
414
            0xD2 => Instruction::RefFunc {
415
0
                func_index: self.read_size()?,
416
            },
417
            // parametric instructions
418
1.25k
            0x1A => Instruction::Drop,
419
116
            0x1B => Instruction::Select { result_types: None },
420
            0x1C => Instruction::Select {
421
0
                result_types: Some(self.read_vec(|d| d.read_value_type())?),
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderRShE16read_instructions_0Cs5HNiFFfDLPG_6decode
Unexecuted instantiation: _RNCNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB4_7DecoderpE16read_instructions_0B8_
422
            },
423
            // variable instructions
424
            0x20 => Instruction::LocalGet {
425
2.89k
                local_index: self.read_size()?,
426
            },
427
            0x21 => Instruction::LocalSet {
428
623
                local_index: self.read_size()?,
429
            },
430
            0x22 => Instruction::LocalTee {
431
1.00k
                local_index: self.read_size()?,
432
            },
433
            0x23 => Instruction::GlobalGet {
434
5.80k
                global_index: self.read_size()?,
435
            },
436
            0x24 => Instruction::GlobalSet {
437
3.24k
                global_index: self.read_size()?,
438
            },
439
            // table instructions
440
            0x25 => Instruction::TableGet {
441
0
                table_index: self.read_size()?,
442
            },
443
            0x26 => Instruction::TableSet {
444
0
                table_index: self.read_size()?,
445
            },
446
            0xFC => {
447
2.66k
                let id = self.read_size()?;
448
449
2.66k
                match id {
450
569
                    0x00 => Instruction::I32TruncSatF32S,
451
504
                    0x01 => Instruction::I32TruncSatF32U,
452
280
                    0x02 => Instruction::I32TruncSatF64S,
453
558
                    0x03 => Instruction::I32TruncSatF64U,
454
179
                    0x04 => Instruction::I64TruncSatF32S,
455
251
                    0x05 => Instruction::I64TruncSatF32U,
456
173
                    0x06 => Instruction::I64TruncSatF64S,
457
146
                    0x07 => Instruction::I64TruncSatF64U,
458
                    0x08 => {
459
0
                        let inst = Instruction::MemoryInit {
460
0
                            data_index: self.read_size()?,
461
                        };
462
463
0
                        self.read_u8()?; // 0x00
464
465
0
                        inst
466
                    }
467
                    0x09 => Instruction::DataDrop {
468
0
                        data_index: self.read_size()?,
469
                    },
470
                    0x0A => {
471
0
                        let inst = Instruction::MemoryCopy;
472
0
473
0
                        self.read_u8()?; // 0x00
474
0
                        self.read_u8()?; // 0x00
475
476
0
                        inst
477
                    }
478
                    0x0B => {
479
0
                        let inst = Instruction::MemoryFill;
480
0
481
0
                        self.read_u8()?; // 0x00
482
483
0
                        inst
484
                    }
485
                    0x0C => Instruction::TableInit {
486
0
                        element_index: self.read_size()?,
487
0
                        table_index: self.read_size()?,
488
                    },
489
                    0x0D => Instruction::ElemDrop {
490
0
                        element_index: self.read_size()?,
491
                    },
492
                    0x0E => Instruction::TableCopy {
493
0
                        dst_table_index: self.read_size()?,
494
0
                        src_table_index: self.read_size()?,
495
                    },
496
                    0x0F => Instruction::TableGrow {
497
0
                        table_index: self.read_size()?,
498
                    },
499
                    0x10 => Instruction::TableSize {
500
0
                        table_index: self.read_size()?,
501
                    },
502
                    0x11 => Instruction::TableFill {
503
0
                        table_index: self.read_size()?,
504
                    },
505
0
                    v => bail!(DecodeError::InvalidSubInstructionId(v)),
506
                }
507
            }
508
            // memory instructions
509
            0x28 => Instruction::I32Load {
510
261
                mem_arg: self.read_mem_arg()?,
511
            },
512
            0x29 => Instruction::I64Load {
513
263
                mem_arg: self.read_mem_arg()?,
514
            },
515
            0x2A => Instruction::F32Load {
516
172
                mem_arg: self.read_mem_arg()?,
517
            },
518
            0x2B => Instruction::F64Load {
519
114
                mem_arg: self.read_mem_arg()?,
520
            },
521
            0x2C => Instruction::I32Load8S {
522
364
                mem_arg: self.read_mem_arg()?,
523
            },
524
            0x2D => Instruction::I32Load8U {
525
377
                mem_arg: self.read_mem_arg()?,
526
            },
527
            0x2E => Instruction::I32Load16S {
528
355
                mem_arg: self.read_mem_arg()?,
529
            },
530
            0x2F => Instruction::I32Load16U {
531
387
                mem_arg: self.read_mem_arg()?,
532
            },
533
            0x30 => Instruction::I64Load8S {
534
180
                mem_arg: self.read_mem_arg()?,
535
            },
536
            0x31 => Instruction::I64Load8U {
537
263
                mem_arg: self.read_mem_arg()?,
538
            },
539
            0x32 => Instruction::I64Load16S {
540
220
                mem_arg: self.read_mem_arg()?,
541
            },
542
            0x33 => Instruction::I64Load16U {
543
65
                mem_arg: self.read_mem_arg()?,
544
            },
545
            0x34 => Instruction::I64Load32S {
546
142
                mem_arg: self.read_mem_arg()?,
547
            },
548
            0x35 => Instruction::I64Load32U {
549
115
                mem_arg: self.read_mem_arg()?,
550
            },
551
            0x36 => Instruction::I32Store {
552
20
                mem_arg: self.read_mem_arg()?,
553
            },
554
            0x37 => Instruction::I64Store {
555
110
                mem_arg: self.read_mem_arg()?,
556
            },
557
            0x38 => Instruction::F32Store {
558
37
                mem_arg: self.read_mem_arg()?,
559
            },
560
            0x39 => Instruction::F64Store {
561
26
                mem_arg: self.read_mem_arg()?,
562
            },
563
            0x3A => Instruction::I32Store8 {
564
44
                mem_arg: self.read_mem_arg()?,
565
            },
566
            0x3B => Instruction::I32Store16 {
567
16
                mem_arg: self.read_mem_arg()?,
568
            },
569
            0x3C => Instruction::I64Store8 {
570
65
                mem_arg: self.read_mem_arg()?,
571
            },
572
            0x3D => Instruction::I64Store16 {
573
27
                mem_arg: self.read_mem_arg()?,
574
            },
575
            0x3E => Instruction::I64Store32 {
576
45
                mem_arg: self.read_mem_arg()?,
577
            },
578
            0x3F => {
579
1.50k
                self.read_u8()?;
580
1.50k
                Instruction::MemorySize
581
            }
582
            0x40 => {
583
574
                self.read_u8()?;
584
574
                Instruction::MemoryGrow
585
            }
586
            /* numerics */
587
            0x41 => Instruction::I32Const {
588
8.04k
                value: self.read_i32()?,
589
            },
590
            0x42 => Instruction::I64Const {
591
3.49k
                value: self.read_i64()?,
592
            },
593
            0x43 => Instruction::F32Const {
594
3.24k
                value: self.read_f32()?,
595
            },
596
            0x44 => Instruction::F64Const {
597
2.38k
                value: self.read_f64()?,
598
            },
599
679
            0x45 => Instruction::I32Eqz,
600
104
            0x46 => Instruction::I32Eq,
601
83
            0x47 => Instruction::I32Ne,
602
86
            0x48 => Instruction::I32LtS,
603
96
            0x49 => Instruction::I32LtU,
604
209
            0x4A => Instruction::I32GtS,
605
35
            0x4B => Instruction::I32GtU,
606
83
            0x4C => Instruction::I32LeS,
607
62
            0x4D => Instruction::I32LeU,
608
58
            0x4E => Instruction::I32GeS,
609
57
            0x4F => Instruction::I32GeU,
610
420
            0x50 => Instruction::I64Eqz,
611
25
            0x51 => Instruction::I64Eq,
612
30
            0x52 => Instruction::I64Ne,
613
27
            0x53 => Instruction::I64LtS,
614
55
            0x54 => Instruction::I64LtU,
615
23
            0x55 => Instruction::I64GtS,
616
89
            0x56 => Instruction::I64GtU,
617
53
            0x57 => Instruction::I64LeS,
618
53
            0x58 => Instruction::I64LeU,
619
49
            0x59 => Instruction::I64GeS,
620
84
            0x5A => Instruction::I64GeU,
621
22
            0x5B => Instruction::F32Eq,
622
27
            0x5C => Instruction::F32Ne,
623
20
            0x5D => Instruction::F32Lt,
624
17
            0x5E => Instruction::F32Gt,
625
30
            0x5F => Instruction::F32Le,
626
34
            0x60 => Instruction::F32Ge,
627
30
            0x61 => Instruction::F64Eq,
628
18
            0x62 => Instruction::F64Ne,
629
8
            0x63 => Instruction::F64Lt,
630
25
            0x64 => Instruction::F64Gt,
631
7
            0x65 => Instruction::F64Le,
632
19
            0x66 => Instruction::F64Ge,
633
745
            0x67 => Instruction::I32Clz,
634
686
            0x68 => Instruction::I32Ctz,
635
570
            0x69 => Instruction::I32Popcnt,
636
50
            0x6A => Instruction::I32Add,
637
132
            0x6B => Instruction::I32Sub,
638
245
            0x6C => Instruction::I32Mul,
639
83
            0x6D => Instruction::I32DivS,
640
150
            0x6E => Instruction::I32DivU,
641
67
            0x6F => Instruction::I32RemS,
642
153
            0x70 => Instruction::I32RemU,
643
182
            0x71 => Instruction::I32And,
644
427
            0x72 => Instruction::I32Or,
645
2.13k
            0x73 => Instruction::I32Xor,
646
82
            0x74 => Instruction::I32Shl,
647
73
            0x75 => Instruction::I32ShrS,
648
78
            0x76 => Instruction::I32ShrU,
649
53
            0x77 => Instruction::I32Rotl,
650
162
            0x78 => Instruction::I32Rotr,
651
556
            0x79 => Instruction::I64Clz,
652
443
            0x7A => Instruction::I64Ctz,
653
645
            0x7B => Instruction::I64Popcnt,
654
25
            0x7C => Instruction::I64Add,
655
65
            0x7D => Instruction::I64Sub,
656
59
            0x7E => Instruction::I64Mul,
657
158
            0x7F => Instruction::I64DivS,
658
116
            0x80 => Instruction::I64DivU,
659
54
            0x81 => Instruction::I64RemS,
660
40
            0x82 => Instruction::I64RemU,
661
117
            0x83 => Instruction::I64And,
662
43
            0x84 => Instruction::I64Or,
663
1.04k
            0x85 => Instruction::I64Xor,
664
83
            0x86 => Instruction::I64Shl,
665
68
            0x87 => Instruction::I64ShrS,
666
30
            0x88 => Instruction::I64ShrU,
667
69
            0x89 => Instruction::I64Rotl,
668
35
            0x8A => Instruction::I64Rotr,
669
1.09k
            0x8B => Instruction::F32Abs,
670
714
            0x8C => Instruction::F32Neg,
671
471
            0x8D => Instruction::F32Ceil,
672
750
            0x8E => Instruction::F32Floor,
673
482
            0x8F => Instruction::F32Trunc,
674
667
            0x90 => Instruction::F32Nearest,
675
1.11k
            0x91 => Instruction::F32Sqrt,
676
54
            0x92 => Instruction::F32Add,
677
144
            0x93 => Instruction::F32Sub,
678
80
            0x94 => Instruction::F32Mul,
679
117
            0x95 => Instruction::F32Div,
680
45
            0x96 => Instruction::F32Min,
681
134
            0x97 => Instruction::F32Max,
682
99
            0x98 => Instruction::F32Copysign,
683
584
            0x99 => Instruction::F64Abs,
684
375
            0x9A => Instruction::F64Neg,
685
636
            0x9B => Instruction::F64Ceil,
686
667
            0x9C => Instruction::F64Floor,
687
475
            0x9D => Instruction::F64Trunc,
688
433
            0x9E => Instruction::F64Nearest,
689
1.58k
            0x9F => Instruction::F64Sqrt,
690
64
            0xA0 => Instruction::F64Add,
691
57
            0xA1 => Instruction::F64Sub,
692
63
            0xA2 => Instruction::F64Mul,
693
38
            0xA3 => Instruction::F64Div,
694
43
            0xA4 => Instruction::F64Min,
695
59
            0xA5 => Instruction::F64Max,
696
103
            0xA6 => Instruction::F64Copysign,
697
485
            0xA7 => Instruction::I32WrapI64,
698
516
            0xA8 => Instruction::I32TruncF32S,
699
379
            0xA9 => Instruction::I32TruncF32U,
700
330
            0xAA => Instruction::I32TruncF64S,
701
488
            0xAB => Instruction::I32TruncF64U,
702
631
            0xAC => Instruction::I64ExtendI32S,
703
547
            0xAD => Instruction::I64ExtendI32U,
704
399
            0xAE => Instruction::I64TruncF32S,
705
124
            0xAF => Instruction::I64TruncF32U,
706
804
            0xB0 => Instruction::I64TruncF64S,
707
242
            0xB1 => Instruction::I64TruncF64U,
708
515
            0xB2 => Instruction::F32ConvertI32S,
709
375
            0xB3 => Instruction::F32ConvertI32U,
710
311
            0xB4 => Instruction::F32ConvertI64S,
711
615
            0xB5 => Instruction::F32ConvertI64U,
712
545
            0xB6 => Instruction::F32DemoteF64,
713
587
            0xB7 => Instruction::F64ConvertI32S,
714
479
            0xB8 => Instruction::F64ConvertI32U,
715
392
            0xB9 => Instruction::F64ConvertI64S,
716
902
            0xBA => Instruction::F64ConvertI64U,
717
611
            0xBB => Instruction::F64PromoteF32,
718
1.42k
            0xBC => Instruction::I32ReinterpretF32,
719
543
            0xBD => Instruction::I64ReinterpretF64,
720
1.08k
            0xBE => Instruction::F32ReinterpretI32,
721
527
            0xBF => Instruction::F64ReinterpretI64,
722
720
            0xC0 => Instruction::I32Extend8S,
723
429
            0xC1 => Instruction::I32Extend16S,
724
550
            0xC2 => Instruction::I64Extend8S,
725
678
            0xC3 => Instruction::I64Extend16S,
726
699
            0xC4 => Instruction::I64Extend32S,
727
0
            _ => unimplemented!("Opcode 0x{:02x} is not implemented", opcode),
728
        };
729
730
131k
        Ok(instr)
731
131k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE16read_instructionCs5HNiFFfDLPG_6decode
Line
Count
Source
362
131k
    fn read_instruction(&mut self) -> Result<Instruction> {
363
131k
        let opcode = match self.read_u8() {
364
131k
            Ok(opcode) => opcode,
365
0
            Err(err) => {
366
0
                return Err(err);
367
            }
368
        };
369
370
131k
        let instr = match opcode {
371
            // control instructions
372
9.90k
            0x00 => Instruction::Unreachable,
373
1.70k
            0x01 => Instruction::Nop,
374
            0x02 => Instruction::Block {
375
                block: Block {
376
4.04k
                    block_type: self.read_block_type().context("instruction block")?,
377
                },
378
            },
379
            0x03 => Instruction::Loop {
380
                block: Block {
381
2.22k
                    block_type: self.read_block_type().context("instruction loop block")?,
382
                },
383
            },
384
            0x04 => Instruction::If {
385
                block: Block {
386
411
                    block_type: self.read_block_type().context("instruction if block")?,
387
                },
388
            },
389
288
            0x05 => Instruction::Else,
390
22.4k
            0x0B => Instruction::End,
391
            0x0C => Instruction::Br {
392
2.53k
                level: self.read_size()?,
393
            },
394
            0x0D => Instruction::BrIf {
395
556
                level: self.read_size()?,
396
            },
397
            0xE => Instruction::BrTable {
398
726
                label_indexes: self.read_vec(|d| d.read_size())?,
399
726
                default_index: self.read_size()?,
400
            },
401
465
            0x0F => Instruction::Return,
402
            0x10 => Instruction::Call {
403
4.35k
                func_index: self.read_size()?,
404
            },
405
            0x11 => Instruction::CallIndirect {
406
461
                type_index: self.read_size()?,
407
461
                table_index: self.read_size()?,
408
            },
409
            // reference instructions
410
            0xD0 => Instruction::RefNull {
411
0
                ref_type: self.read_reference_type()?,
412
            },
413
0
            0xD1 => Instruction::RefIsNull,
414
            0xD2 => Instruction::RefFunc {
415
0
                func_index: self.read_size()?,
416
            },
417
            // parametric instructions
418
1.25k
            0x1A => Instruction::Drop,
419
116
            0x1B => Instruction::Select { result_types: None },
420
            0x1C => Instruction::Select {
421
0
                result_types: Some(self.read_vec(|d| d.read_value_type())?),
422
            },
423
            // variable instructions
424
            0x20 => Instruction::LocalGet {
425
2.89k
                local_index: self.read_size()?,
426
            },
427
            0x21 => Instruction::LocalSet {
428
623
                local_index: self.read_size()?,
429
            },
430
            0x22 => Instruction::LocalTee {
431
1.00k
                local_index: self.read_size()?,
432
            },
433
            0x23 => Instruction::GlobalGet {
434
5.80k
                global_index: self.read_size()?,
435
            },
436
            0x24 => Instruction::GlobalSet {
437
3.24k
                global_index: self.read_size()?,
438
            },
439
            // table instructions
440
            0x25 => Instruction::TableGet {
441
0
                table_index: self.read_size()?,
442
            },
443
            0x26 => Instruction::TableSet {
444
0
                table_index: self.read_size()?,
445
            },
446
            0xFC => {
447
2.66k
                let id = self.read_size()?;
448
449
2.66k
                match id {
450
569
                    0x00 => Instruction::I32TruncSatF32S,
451
504
                    0x01 => Instruction::I32TruncSatF32U,
452
280
                    0x02 => Instruction::I32TruncSatF64S,
453
558
                    0x03 => Instruction::I32TruncSatF64U,
454
179
                    0x04 => Instruction::I64TruncSatF32S,
455
251
                    0x05 => Instruction::I64TruncSatF32U,
456
173
                    0x06 => Instruction::I64TruncSatF64S,
457
146
                    0x07 => Instruction::I64TruncSatF64U,
458
                    0x08 => {
459
0
                        let inst = Instruction::MemoryInit {
460
0
                            data_index: self.read_size()?,
461
                        };
462
463
0
                        self.read_u8()?; // 0x00
464
465
0
                        inst
466
                    }
467
                    0x09 => Instruction::DataDrop {
468
0
                        data_index: self.read_size()?,
469
                    },
470
                    0x0A => {
471
0
                        let inst = Instruction::MemoryCopy;
472
0
473
0
                        self.read_u8()?; // 0x00
474
0
                        self.read_u8()?; // 0x00
475
476
0
                        inst
477
                    }
478
                    0x0B => {
479
0
                        let inst = Instruction::MemoryFill;
480
0
481
0
                        self.read_u8()?; // 0x00
482
483
0
                        inst
484
                    }
485
                    0x0C => Instruction::TableInit {
486
0
                        element_index: self.read_size()?,
487
0
                        table_index: self.read_size()?,
488
                    },
489
                    0x0D => Instruction::ElemDrop {
490
0
                        element_index: self.read_size()?,
491
                    },
492
                    0x0E => Instruction::TableCopy {
493
0
                        dst_table_index: self.read_size()?,
494
0
                        src_table_index: self.read_size()?,
495
                    },
496
                    0x0F => Instruction::TableGrow {
497
0
                        table_index: self.read_size()?,
498
                    },
499
                    0x10 => Instruction::TableSize {
500
0
                        table_index: self.read_size()?,
501
                    },
502
                    0x11 => Instruction::TableFill {
503
0
                        table_index: self.read_size()?,
504
                    },
505
0
                    v => bail!(DecodeError::InvalidSubInstructionId(v)),
506
                }
507
            }
508
            // memory instructions
509
            0x28 => Instruction::I32Load {
510
261
                mem_arg: self.read_mem_arg()?,
511
            },
512
            0x29 => Instruction::I64Load {
513
263
                mem_arg: self.read_mem_arg()?,
514
            },
515
            0x2A => Instruction::F32Load {
516
172
                mem_arg: self.read_mem_arg()?,
517
            },
518
            0x2B => Instruction::F64Load {
519
114
                mem_arg: self.read_mem_arg()?,
520
            },
521
            0x2C => Instruction::I32Load8S {
522
364
                mem_arg: self.read_mem_arg()?,
523
            },
524
            0x2D => Instruction::I32Load8U {
525
377
                mem_arg: self.read_mem_arg()?,
526
            },
527
            0x2E => Instruction::I32Load16S {
528
355
                mem_arg: self.read_mem_arg()?,
529
            },
530
            0x2F => Instruction::I32Load16U {
531
387
                mem_arg: self.read_mem_arg()?,
532
            },
533
            0x30 => Instruction::I64Load8S {
534
180
                mem_arg: self.read_mem_arg()?,
535
            },
536
            0x31 => Instruction::I64Load8U {
537
263
                mem_arg: self.read_mem_arg()?,
538
            },
539
            0x32 => Instruction::I64Load16S {
540
220
                mem_arg: self.read_mem_arg()?,
541
            },
542
            0x33 => Instruction::I64Load16U {
543
65
                mem_arg: self.read_mem_arg()?,
544
            },
545
            0x34 => Instruction::I64Load32S {
546
142
                mem_arg: self.read_mem_arg()?,
547
            },
548
            0x35 => Instruction::I64Load32U {
549
115
                mem_arg: self.read_mem_arg()?,
550
            },
551
            0x36 => Instruction::I32Store {
552
20
                mem_arg: self.read_mem_arg()?,
553
            },
554
            0x37 => Instruction::I64Store {
555
110
                mem_arg: self.read_mem_arg()?,
556
            },
557
            0x38 => Instruction::F32Store {
558
37
                mem_arg: self.read_mem_arg()?,
559
            },
560
            0x39 => Instruction::F64Store {
561
26
                mem_arg: self.read_mem_arg()?,
562
            },
563
            0x3A => Instruction::I32Store8 {
564
44
                mem_arg: self.read_mem_arg()?,
565
            },
566
            0x3B => Instruction::I32Store16 {
567
16
                mem_arg: self.read_mem_arg()?,
568
            },
569
            0x3C => Instruction::I64Store8 {
570
65
                mem_arg: self.read_mem_arg()?,
571
            },
572
            0x3D => Instruction::I64Store16 {
573
27
                mem_arg: self.read_mem_arg()?,
574
            },
575
            0x3E => Instruction::I64Store32 {
576
45
                mem_arg: self.read_mem_arg()?,
577
            },
578
            0x3F => {
579
1.50k
                self.read_u8()?;
580
1.50k
                Instruction::MemorySize
581
            }
582
            0x40 => {
583
574
                self.read_u8()?;
584
574
                Instruction::MemoryGrow
585
            }
586
            /* numerics */
587
            0x41 => Instruction::I32Const {
588
8.04k
                value: self.read_i32()?,
589
            },
590
            0x42 => Instruction::I64Const {
591
3.49k
                value: self.read_i64()?,
592
            },
593
            0x43 => Instruction::F32Const {
594
3.24k
                value: self.read_f32()?,
595
            },
596
            0x44 => Instruction::F64Const {
597
2.38k
                value: self.read_f64()?,
598
            },
599
679
            0x45 => Instruction::I32Eqz,
600
104
            0x46 => Instruction::I32Eq,
601
83
            0x47 => Instruction::I32Ne,
602
86
            0x48 => Instruction::I32LtS,
603
96
            0x49 => Instruction::I32LtU,
604
209
            0x4A => Instruction::I32GtS,
605
35
            0x4B => Instruction::I32GtU,
606
83
            0x4C => Instruction::I32LeS,
607
62
            0x4D => Instruction::I32LeU,
608
58
            0x4E => Instruction::I32GeS,
609
57
            0x4F => Instruction::I32GeU,
610
420
            0x50 => Instruction::I64Eqz,
611
25
            0x51 => Instruction::I64Eq,
612
30
            0x52 => Instruction::I64Ne,
613
27
            0x53 => Instruction::I64LtS,
614
55
            0x54 => Instruction::I64LtU,
615
23
            0x55 => Instruction::I64GtS,
616
89
            0x56 => Instruction::I64GtU,
617
53
            0x57 => Instruction::I64LeS,
618
53
            0x58 => Instruction::I64LeU,
619
49
            0x59 => Instruction::I64GeS,
620
84
            0x5A => Instruction::I64GeU,
621
22
            0x5B => Instruction::F32Eq,
622
27
            0x5C => Instruction::F32Ne,
623
20
            0x5D => Instruction::F32Lt,
624
17
            0x5E => Instruction::F32Gt,
625
30
            0x5F => Instruction::F32Le,
626
34
            0x60 => Instruction::F32Ge,
627
30
            0x61 => Instruction::F64Eq,
628
18
            0x62 => Instruction::F64Ne,
629
8
            0x63 => Instruction::F64Lt,
630
25
            0x64 => Instruction::F64Gt,
631
7
            0x65 => Instruction::F64Le,
632
19
            0x66 => Instruction::F64Ge,
633
745
            0x67 => Instruction::I32Clz,
634
686
            0x68 => Instruction::I32Ctz,
635
570
            0x69 => Instruction::I32Popcnt,
636
50
            0x6A => Instruction::I32Add,
637
132
            0x6B => Instruction::I32Sub,
638
245
            0x6C => Instruction::I32Mul,
639
83
            0x6D => Instruction::I32DivS,
640
150
            0x6E => Instruction::I32DivU,
641
67
            0x6F => Instruction::I32RemS,
642
153
            0x70 => Instruction::I32RemU,
643
182
            0x71 => Instruction::I32And,
644
427
            0x72 => Instruction::I32Or,
645
2.13k
            0x73 => Instruction::I32Xor,
646
82
            0x74 => Instruction::I32Shl,
647
73
            0x75 => Instruction::I32ShrS,
648
78
            0x76 => Instruction::I32ShrU,
649
53
            0x77 => Instruction::I32Rotl,
650
162
            0x78 => Instruction::I32Rotr,
651
556
            0x79 => Instruction::I64Clz,
652
443
            0x7A => Instruction::I64Ctz,
653
645
            0x7B => Instruction::I64Popcnt,
654
25
            0x7C => Instruction::I64Add,
655
65
            0x7D => Instruction::I64Sub,
656
59
            0x7E => Instruction::I64Mul,
657
158
            0x7F => Instruction::I64DivS,
658
116
            0x80 => Instruction::I64DivU,
659
54
            0x81 => Instruction::I64RemS,
660
40
            0x82 => Instruction::I64RemU,
661
117
            0x83 => Instruction::I64And,
662
43
            0x84 => Instruction::I64Or,
663
1.04k
            0x85 => Instruction::I64Xor,
664
83
            0x86 => Instruction::I64Shl,
665
68
            0x87 => Instruction::I64ShrS,
666
30
            0x88 => Instruction::I64ShrU,
667
69
            0x89 => Instruction::I64Rotl,
668
35
            0x8A => Instruction::I64Rotr,
669
1.09k
            0x8B => Instruction::F32Abs,
670
714
            0x8C => Instruction::F32Neg,
671
471
            0x8D => Instruction::F32Ceil,
672
750
            0x8E => Instruction::F32Floor,
673
482
            0x8F => Instruction::F32Trunc,
674
667
            0x90 => Instruction::F32Nearest,
675
1.11k
            0x91 => Instruction::F32Sqrt,
676
54
            0x92 => Instruction::F32Add,
677
144
            0x93 => Instruction::F32Sub,
678
80
            0x94 => Instruction::F32Mul,
679
117
            0x95 => Instruction::F32Div,
680
45
            0x96 => Instruction::F32Min,
681
134
            0x97 => Instruction::F32Max,
682
99
            0x98 => Instruction::F32Copysign,
683
584
            0x99 => Instruction::F64Abs,
684
375
            0x9A => Instruction::F64Neg,
685
636
            0x9B => Instruction::F64Ceil,
686
667
            0x9C => Instruction::F64Floor,
687
475
            0x9D => Instruction::F64Trunc,
688
433
            0x9E => Instruction::F64Nearest,
689
1.58k
            0x9F => Instruction::F64Sqrt,
690
64
            0xA0 => Instruction::F64Add,
691
57
            0xA1 => Instruction::F64Sub,
692
63
            0xA2 => Instruction::F64Mul,
693
38
            0xA3 => Instruction::F64Div,
694
43
            0xA4 => Instruction::F64Min,
695
59
            0xA5 => Instruction::F64Max,
696
103
            0xA6 => Instruction::F64Copysign,
697
485
            0xA7 => Instruction::I32WrapI64,
698
516
            0xA8 => Instruction::I32TruncF32S,
699
379
            0xA9 => Instruction::I32TruncF32U,
700
330
            0xAA => Instruction::I32TruncF64S,
701
488
            0xAB => Instruction::I32TruncF64U,
702
631
            0xAC => Instruction::I64ExtendI32S,
703
547
            0xAD => Instruction::I64ExtendI32U,
704
399
            0xAE => Instruction::I64TruncF32S,
705
124
            0xAF => Instruction::I64TruncF32U,
706
804
            0xB0 => Instruction::I64TruncF64S,
707
242
            0xB1 => Instruction::I64TruncF64U,
708
515
            0xB2 => Instruction::F32ConvertI32S,
709
375
            0xB3 => Instruction::F32ConvertI32U,
710
311
            0xB4 => Instruction::F32ConvertI64S,
711
615
            0xB5 => Instruction::F32ConvertI64U,
712
545
            0xB6 => Instruction::F32DemoteF64,
713
587
            0xB7 => Instruction::F64ConvertI32S,
714
479
            0xB8 => Instruction::F64ConvertI32U,
715
392
            0xB9 => Instruction::F64ConvertI64S,
716
902
            0xBA => Instruction::F64ConvertI64U,
717
611
            0xBB => Instruction::F64PromoteF32,
718
1.42k
            0xBC => Instruction::I32ReinterpretF32,
719
543
            0xBD => Instruction::I64ReinterpretF64,
720
1.08k
            0xBE => Instruction::F32ReinterpretI32,
721
527
            0xBF => Instruction::F64ReinterpretI64,
722
720
            0xC0 => Instruction::I32Extend8S,
723
429
            0xC1 => Instruction::I32Extend16S,
724
550
            0xC2 => Instruction::I64Extend8S,
725
678
            0xC3 => Instruction::I64Extend16S,
726
699
            0xC4 => Instruction::I64Extend32S,
727
0
            _ => unimplemented!("Opcode 0x{:02x} is not implemented", opcode),
728
        };
729
730
131k
        Ok(instr)
731
131k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE16read_instructionB6_
732
733
5.88k
    fn read_instruction_and_end(&mut self) -> Result<Instruction> {
734
5.88k
        let instr = self.read_instruction()?;
735
5.88k
        let end = self.read_size()?;
736
5.88k
        if end != 0x0B {
737
0
            bail!(DecodeError::Expected("0x0B".to_owned()));
738
5.88k
        }
739
5.88k
740
5.88k
        Ok(instr)
741
5.88k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE24read_instruction_and_endCs5HNiFFfDLPG_6decode
Line
Count
Source
733
5.88k
    fn read_instruction_and_end(&mut self) -> Result<Instruction> {
734
5.88k
        let instr = self.read_instruction()?;
735
5.88k
        let end = self.read_size()?;
736
5.88k
        if end != 0x0B {
737
0
            bail!(DecodeError::Expected("0x0B".to_owned()));
738
5.88k
        }
739
5.88k
740
5.88k
        Ok(instr)
741
5.88k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE24read_instruction_and_endB6_
742
743
50.3k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
50.3k
        let size = self.read_size()?;
745
50.3k
        let mut items = Vec::with_capacity(size as usize);
746
50.3k
747
50.3k
        for _ in 0..size {
748
70.2k
            items.push(decode_fn(self)?);
749
        }
750
751
50.3k
        Ok(items)
752
50.3k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecINtNtCsbpSlAbJY2yh_5alloc3vec3VecNtNtNtB5_6binary5types9ValueTypeENCNCNvB2_19decode_code_section00ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
15.8k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
15.8k
        let size = self.read_size()?;
745
15.8k
        let mut items = Vec::with_capacity(size as usize);
746
15.8k
747
15.8k
        for _ in 0..size {
748
3.10k
            items.push(decode_fn(self)?);
749
        }
750
751
15.8k
        Ok(items)
752
15.8k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types10MemoryTypeNCNvB2_21decode_memory_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
1.41k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
1.41k
        let size = self.read_size()?;
745
1.41k
        let mut items = Vec::with_capacity(size as usize);
746
1.41k
747
1.41k
        for _ in 0..size {
748
1.41k
            items.push(decode_fn(self)?);
749
        }
750
751
1.41k
        Ok(items)
752
1.41k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types4DataNCNvB2_19decode_data_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
176
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
176
        let size = self.read_size()?;
745
176
        let mut items = Vec::with_capacity(size as usize);
746
176
747
176
        for _ in 0..size {
748
776
            items.push(decode_fn(self)?);
749
        }
750
751
176
        Ok(items)
752
176
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types6ExportNCNvB2_21decode_export_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
897
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
897
        let size = self.read_size()?;
745
897
        let mut items = Vec::with_capacity(size as usize);
746
897
747
897
        for _ in 0..size {
748
5.46k
            items.push(decode_fn(self)?);
749
        }
750
751
897
        Ok(items)
752
897
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types6GlobalNCNvB2_21decode_global_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
1.67k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
1.67k
        let size = self.read_size()?;
745
1.67k
        let mut items = Vec::with_capacity(size as usize);
746
1.67k
747
1.67k
        for _ in 0..size {
748
3.51k
            items.push(decode_fn(self)?);
749
        }
750
751
1.67k
        Ok(items)
752
1.67k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types6ImportNCNvB2_21decode_import_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
2.55k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
2.55k
        let size = self.read_size()?;
745
2.55k
        let mut items = Vec::with_capacity(size as usize);
746
2.55k
747
2.55k
        for _ in 0..size {
748
4.32k
            items.push(decode_fn(self)?);
749
        }
750
751
2.55k
        Ok(items)
752
2.55k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types7ElementNCNvB2_22decode_element_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
252
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
252
        let size = self.read_size()?;
745
252
        let mut items = Vec::with_capacity(size as usize);
746
252
747
252
        for _ in 0..size {
748
1.58k
            items.push(decode_fn(self)?);
749
        }
750
751
252
        Ok(items)
752
252
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types8FuncTypeNCNvB2_19decode_type_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
4.63k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
4.63k
        let size = self.read_size()?;
745
4.63k
        let mut items = Vec::with_capacity(size as usize);
746
4.63k
747
4.63k
        for _ in 0..size {
748
5.68k
            items.push(decode_fn(self)?);
749
        }
750
751
4.63k
        Ok(items)
752
4.63k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types9TableTypeNCNvB2_20decode_table_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
1.03k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
1.03k
        let size = self.read_size()?;
745
1.03k
        let mut items = Vec::with_capacity(size as usize);
746
1.03k
747
1.03k
        for _ in 0..size {
748
1.03k
            items.push(decode_fn(self)?);
749
        }
750
751
1.03k
        Ok(items)
752
1.03k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types9ValueTypeNCNCNvB2_19decode_type_section00ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
5.68k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
5.68k
        let size = self.read_size()?;
745
5.68k
        let mut items = Vec::with_capacity(size as usize);
746
5.68k
747
5.68k
        for _ in 0..size {
748
2.68k
            items.push(decode_fn(self)?);
749
        }
750
751
5.68k
        Ok(items)
752
5.68k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types9ValueTypeNCNCNvB2_19decode_type_section0s_0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
5.68k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
5.68k
        let size = self.read_size()?;
745
5.68k
        let mut items = Vec::with_capacity(size as usize);
746
5.68k
747
5.68k
        for _ in 0..size {
748
4.12k
            items.push(decode_fn(self)?);
749
        }
750
751
5.68k
        Ok(items)
752
5.68k
    }
Unexecuted instantiation: _RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtB5_6binary5types9ValueTypeNCNvB2_16read_instructions_0ECs5HNiFFfDLPG_6decode
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecNtNtNtNtB5_6binary7section4code4CodeNCNvB2_19decode_code_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
4.09k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
4.09k
        let size = self.read_size()?;
745
4.09k
        let mut items = Vec::with_capacity(size as usize);
746
4.09k
747
4.09k
        for _ in 0..size {
748
15.8k
            items.push(decode_fn(self)?);
749
        }
750
751
4.09k
        Ok(items)
752
4.09k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecmNCNCNvB2_22decode_element_section00ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
1.58k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
1.58k
        let size = self.read_size()?;
745
1.58k
        let mut items = Vec::with_capacity(size as usize);
746
1.58k
747
1.58k
        for _ in 0..size {
748
2.41k
            items.push(decode_fn(self)?);
749
        }
750
751
1.58k
        Ok(items)
752
1.58k
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecmNCNvB2_16read_instruction0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
726
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
726
        let size = self.read_size()?;
745
726
        let mut items = Vec::with_capacity(size as usize);
746
726
747
726
        for _ in 0..size {
748
2.47k
            items.push(decode_fn(self)?);
749
        }
750
751
726
        Ok(items)
752
726
    }
_RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderRShE8read_vecmNCNvB2_23decode_function_section0ECs5HNiFFfDLPG_6decode
Line
Count
Source
743
4.09k
    fn read_vec<T>(&mut self, decode_fn: impl Fn(&mut Self) -> Result<T>) -> Result<Vec<T>> {
744
4.09k
        let size = self.read_size()?;
745
4.09k
        let mut items = Vec::with_capacity(size as usize);
746
4.09k
747
4.09k
        for _ in 0..size {
748
15.8k
            items.push(decode_fn(self)?);
749
        }
750
751
4.09k
        Ok(items)
752
4.09k
    }
Unexecuted instantiation: _RINvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB3_7DecoderpE8read_vecppEB7_
753
754
202k
    fn read_u8(&mut self) -> Result<u8> {
755
202k
        let mut buf = [0; 1];
756
202k
        let result = self.reader.read_exact(&mut buf);
757
202k
758
202k
        match result {
759
202k
            Ok(_) => Ok(buf[0]),
760
0
            Err(_) => bail!(DecodeError::Expected("u8".to_owned())),
761
        }
762
202k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE7read_u8Cs5HNiFFfDLPG_6decode
Line
Count
Source
754
202k
    fn read_u8(&mut self) -> Result<u8> {
755
202k
        let mut buf = [0; 1];
756
202k
        let result = self.reader.read_exact(&mut buf);
757
202k
758
202k
        match result {
759
202k
            Ok(_) => Ok(buf[0]),
760
0
            Err(_) => bail!(DecodeError::Expected("u8".to_owned())),
761
        }
762
202k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE7read_u8B6_
763
764
8.04k
    fn read_i32(&mut self) -> Result<i32> {
765
8.04k
        let size_result = leb128::read::signed(&mut self.reader);
766
8.04k
767
8.04k
        match size_result {
768
8.04k
            Ok(size) => Ok(size as i32),
769
0
            Err(_) => bail!(DecodeError::Expected("i32".to_owned())),
770
        }
771
8.04k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE8read_i32Cs5HNiFFfDLPG_6decode
Line
Count
Source
764
8.04k
    fn read_i32(&mut self) -> Result<i32> {
765
8.04k
        let size_result = leb128::read::signed(&mut self.reader);
766
8.04k
767
8.04k
        match size_result {
768
8.04k
            Ok(size) => Ok(size as i32),
769
0
            Err(_) => bail!(DecodeError::Expected("i32".to_owned())),
770
        }
771
8.04k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE8read_i32B6_
772
773
3.49k
    fn read_i64(&mut self) -> Result<i64> {
774
3.49k
        let size_result = leb128::read::signed(&mut self.reader);
775
3.49k
776
3.49k
        match size_result {
777
3.49k
            Ok(size) => Ok(size),
778
0
            Err(_) => bail!(DecodeError::Expected("i64".to_owned())),
779
        }
780
3.49k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE8read_i64Cs5HNiFFfDLPG_6decode
Line
Count
Source
773
3.49k
    fn read_i64(&mut self) -> Result<i64> {
774
3.49k
        let size_result = leb128::read::signed(&mut self.reader);
775
3.49k
776
3.49k
        match size_result {
777
3.49k
            Ok(size) => Ok(size),
778
0
            Err(_) => bail!(DecodeError::Expected("i64".to_owned())),
779
        }
780
3.49k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE8read_i64B6_
781
782
3.24k
    fn read_f32(&mut self) -> Result<f32> {
783
3.24k
        let mut buf = [0; 4];
784
3.24k
        let result = self.reader.read_exact(&mut buf);
785
3.24k
786
3.24k
        match result {
787
3.24k
            Ok(_) => Ok(f32::from_le_bytes(buf)),
788
0
            Err(_) => bail!(DecodeError::Expected("f32".to_owned())),
789
        }
790
3.24k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE8read_f32Cs5HNiFFfDLPG_6decode
Line
Count
Source
782
3.24k
    fn read_f32(&mut self) -> Result<f32> {
783
3.24k
        let mut buf = [0; 4];
784
3.24k
        let result = self.reader.read_exact(&mut buf);
785
3.24k
786
3.24k
        match result {
787
3.24k
            Ok(_) => Ok(f32::from_le_bytes(buf)),
788
0
            Err(_) => bail!(DecodeError::Expected("f32".to_owned())),
789
        }
790
3.24k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE8read_f32B6_
791
792
2.38k
    fn read_f64(&mut self) -> Result<f64> {
793
2.38k
        let mut buf = [0; 8];
794
2.38k
        let result = self.reader.read_exact(&mut buf);
795
2.38k
796
2.38k
        match result {
797
2.38k
            Ok(_) => Ok(f64::from_le_bytes(buf)),
798
0
            Err(_) => bail!(DecodeError::Expected("f64".to_owned())),
799
        }
800
2.38k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE8read_f64Cs5HNiFFfDLPG_6decode
Line
Count
Source
792
2.38k
    fn read_f64(&mut self) -> Result<f64> {
793
2.38k
        let mut buf = [0; 8];
794
2.38k
        let result = self.reader.read_exact(&mut buf);
795
2.38k
796
2.38k
        match result {
797
2.38k
            Ok(_) => Ok(f64::from_le_bytes(buf)),
798
0
            Err(_) => bail!(DecodeError::Expected("f64".to_owned())),
799
        }
800
2.38k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE8read_f64B6_
801
802
21.4k
    fn read_section(&mut self) -> Result<(SectionId, u32)> {
803
21.4k
        let id = self.read_u8().context("read section id")?;
804
21.4k
        let id = SectionId::from(id);
805
21.4k
        if id.is_unknown() {
806
0
            bail!(DecodeError::InvalidSectionId(id));
807
21.4k
        }
808
809
21.4k
        let size = self.read_size().context("read section size")?;
810
811
21.4k
        Ok((id, size))
812
21.4k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE12read_sectionCs5HNiFFfDLPG_6decode
Line
Count
Source
802
21.4k
    fn read_section(&mut self) -> Result<(SectionId, u32)> {
803
21.4k
        let id = self.read_u8().context("read section id")?;
804
21.4k
        let id = SectionId::from(id);
805
21.4k
        if id.is_unknown() {
806
0
            bail!(DecodeError::InvalidSectionId(id));
807
21.4k
        }
808
809
21.4k
        let size = self.read_size().context("read section size")?;
810
811
21.4k
        Ok((id, size))
812
21.4k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE12read_sectionB6_
813
814
179k
    fn read_size(&mut self) -> Result<u32> {
815
179k
        let size_result = leb128::read::unsigned(&mut self.reader);
816
179k
817
179k
        match size_result {
818
179k
            Ok(size) => Ok(size as u32),
819
0
            Err(_) => bail!(DecodeError::Expected("size(leb128 unsigned)".to_owned())),
820
        }
821
179k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE9read_sizeCs5HNiFFfDLPG_6decode
Line
Count
Source
814
179k
    fn read_size(&mut self) -> Result<u32> {
815
179k
        let size_result = leb128::read::unsigned(&mut self.reader);
816
179k
817
179k
        match size_result {
818
179k
            Ok(size) => Ok(size as u32),
819
0
            Err(_) => bail!(DecodeError::Expected("size(leb128 unsigned)".to_owned())),
820
        }
821
179k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE9read_sizeB6_
822
823
16.5k
    fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
824
16.5k
        let mut bytes = vec![0; size];
825
16.5k
        let result = self.reader.read_exact(&mut bytes);
826
16.5k
827
16.5k
        match result {
828
16.5k
            Ok(_) => Ok(bytes),
829
0
            Err(_) => bail!(DecodeError::Expected(format!("{} bytes", size))),
830
        }
831
16.5k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE10read_bytesCs5HNiFFfDLPG_6decode
Line
Count
Source
823
16.5k
    fn read_bytes(&mut self, size: usize) -> Result<Vec<u8>> {
824
16.5k
        let mut bytes = vec![0; size];
825
16.5k
        let result = self.reader.read_exact(&mut bytes);
826
16.5k
827
16.5k
        match result {
828
16.5k
            Ok(_) => Ok(bytes),
829
0
            Err(_) => bail!(DecodeError::Expected(format!("{} bytes", size))),
830
        }
831
16.5k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE10read_bytesB6_
832
833
3.66k
    fn read_mem_arg(&mut self) -> Result<MemArg> {
834
3.66k
        Ok(MemArg {
835
3.66k
            align: self.read_size()?,
836
3.66k
            offset: self.read_size()?,
837
        })
838
3.66k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE12read_mem_argCs5HNiFFfDLPG_6decode
Line
Count
Source
833
3.66k
    fn read_mem_arg(&mut self) -> Result<MemArg> {
834
3.66k
        Ok(MemArg {
835
3.66k
            align: self.read_size()?,
836
3.66k
            offset: self.read_size()?,
837
        })
838
3.66k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE12read_mem_argB6_
839
840
1.32k
    fn read_reference_type(&mut self) -> Result<RefType> {
841
1.32k
        let type_id = self.read_u8()?;
842
843
1.32k
        match type_id {
844
1.32k
            0x70 => Ok(RefType::FuncRef),
845
0
            0x6F => Ok(RefType::ExternRef),
846
0
            _ => bail!(DecodeError::InvalidRefType),
847
        }
848
1.32k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE19read_reference_typeCs5HNiFFfDLPG_6decode
Line
Count
Source
840
1.32k
    fn read_reference_type(&mut self) -> Result<RefType> {
841
1.32k
        let type_id = self.read_u8()?;
842
843
1.32k
        match type_id {
844
1.32k
            0x70 => Ok(RefType::FuncRef),
845
0
            0x6F => Ok(RefType::ExternRef),
846
0
            _ => bail!(DecodeError::InvalidRefType),
847
        }
848
1.32k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE19read_reference_typeB6_
849
850
6.68k
    fn read_block_type(&mut self) -> Result<BlockType> {
851
6.68k
        match self.read_value_type() {
852
1.66k
            Ok(value_type) => Ok(BlockType::Value(vec![value_type])),
853
5.01k
            Err(err) => match err.downcast_ref::<DecodeError>() {
854
5.01k
                Some(err) => {
855
5.01k
                    if let DecodeError::InvalidValueType(v) = err {
856
5.01k
                        if *v == 0x40 {
857
3.06k
                            Ok(BlockType::Empty)
858
                        } else {
859
1.95k
                            Ok(BlockType::TypeIndex((*v).into()))
860
                        }
861
                    } else {
862
0
                        Err(err.clone().into())
863
                    }
864
                }
865
0
                None => Err(err),
866
            },
867
        }
868
6.68k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE15read_block_typeCs5HNiFFfDLPG_6decode
Line
Count
Source
850
6.68k
    fn read_block_type(&mut self) -> Result<BlockType> {
851
6.68k
        match self.read_value_type() {
852
1.66k
            Ok(value_type) => Ok(BlockType::Value(vec![value_type])),
853
5.01k
            Err(err) => match err.downcast_ref::<DecodeError>() {
854
5.01k
                Some(err) => {
855
5.01k
                    if let DecodeError::InvalidValueType(v) = err {
856
5.01k
                        if *v == 0x40 {
857
3.06k
                            Ok(BlockType::Empty)
858
                        } else {
859
1.95k
                            Ok(BlockType::TypeIndex((*v).into()))
860
                        }
861
                    } else {
862
0
                        Err(err.clone().into())
863
                    }
864
                }
865
0
                None => Err(err),
866
            },
867
        }
868
6.68k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE15read_block_typeB6_
869
870
22.2k
    fn read_value_type(&mut self) -> Result<ValueType> {
871
22.2k
        let type_id = self.read_u8()?;
872
873
22.2k
        let ty = match type_id {
874
10.6k
            0x7F => ValueType::I32,
875
3.06k
            0x7E => ValueType::I64,
876
2.03k
            0x7D => ValueType::F32,
877
1.49k
            0x7C => ValueType::F64,
878
0
            0x7B => ValueType::V128,
879
0
            0x70 => ValueType::FuncRef,
880
0
            0x6F => ValueType::ExternRef,
881
5.01k
            v => bail!(DecodeError::InvalidValueType(v)),
882
        };
883
884
17.2k
        Ok(ty)
885
22.2k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE15read_value_typeCs5HNiFFfDLPG_6decode
Line
Count
Source
870
22.2k
    fn read_value_type(&mut self) -> Result<ValueType> {
871
22.2k
        let type_id = self.read_u8()?;
872
873
22.2k
        let ty = match type_id {
874
10.6k
            0x7F => ValueType::I32,
875
3.06k
            0x7E => ValueType::I64,
876
2.03k
            0x7D => ValueType::F32,
877
1.49k
            0x7C => ValueType::F64,
878
0
            0x7B => ValueType::V128,
879
0
            0x70 => ValueType::FuncRef,
880
0
            0x6F => ValueType::ExternRef,
881
5.01k
            v => bail!(DecodeError::InvalidValueType(v)),
882
        };
883
884
17.2k
        Ok(ty)
885
22.2k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE15read_value_typeB6_
886
887
3.07k
    fn read_limits(&mut self) -> Result<Limits> {
888
3.07k
        match self.read_u8()? {
889
            0x00 => Ok(Limits {
890
1.74k
                min: self.read_size()?,
891
1.74k
                max: None,
892
            }),
893
            0x01 => Ok(Limits {
894
1.33k
                min: self.read_size()?,
895
1.33k
                max: Some(self.read_size()?),
896
            }),
897
0
            _ => bail!(DecodeError::InvalidLimitsKind),
898
        }
899
3.07k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE11read_limitsCs5HNiFFfDLPG_6decode
Line
Count
Source
887
3.07k
    fn read_limits(&mut self) -> Result<Limits> {
888
3.07k
        match self.read_u8()? {
889
            0x00 => Ok(Limits {
890
1.74k
                min: self.read_size()?,
891
1.74k
                max: None,
892
            }),
893
            0x01 => Ok(Limits {
894
1.33k
                min: self.read_size()?,
895
1.33k
                max: Some(self.read_size()?),
896
            }),
897
0
            _ => bail!(DecodeError::InvalidLimitsKind),
898
        }
899
3.07k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE11read_limitsB6_
900
901
14.1k
    fn read_name(&mut self) -> Result<String> {
902
14.1k
        let size = self.read_size()?;
903
14.1k
        let mut buf = vec![0; size as usize];
904
14.1k
        let result = self.reader.read_exact(&mut buf);
905
14.1k
906
14.1k
        match result {
907
14.1k
            Ok(_) => Ok(String::from_utf8(buf).unwrap()),
908
0
            Err(_) => bail!(DecodeError::Expected("name".to_owned())),
909
        }
910
14.1k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE9read_nameCs5HNiFFfDLPG_6decode
Line
Count
Source
901
14.1k
    fn read_name(&mut self) -> Result<String> {
902
14.1k
        let size = self.read_size()?;
903
14.1k
        let mut buf = vec![0; size as usize];
904
14.1k
        let result = self.reader.read_exact(&mut buf);
905
14.1k
906
14.1k
        match result {
907
14.1k
            Ok(_) => Ok(String::from_utf8(buf).unwrap()),
908
0
            Err(_) => bail!(DecodeError::Expected("name".to_owned())),
909
        }
910
14.1k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE9read_nameB6_
911
912
2.13k
    fn read_global_type(&mut self) -> Result<GlobalType> {
913
2.13k
        let value_type = self.read_value_type()?;
914
2.13k
        let mutable = self.read_u8()? == 0x01;
915
916
2.13k
        Ok(GlobalType {
917
2.13k
            value_type,
918
2.13k
            mutable,
919
2.13k
        })
920
2.13k
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE16read_global_typeCs5HNiFFfDLPG_6decode
Line
Count
Source
912
2.13k
    fn read_global_type(&mut self) -> Result<GlobalType> {
913
2.13k
        let value_type = self.read_value_type()?;
914
2.13k
        let mutable = self.read_u8()? == 0x01;
915
916
2.13k
        Ok(GlobalType {
917
2.13k
            value_type,
918
2.13k
            mutable,
919
2.13k
        })
920
2.13k
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE16read_global_typeB6_
921
922
288
    fn read_table_type(&mut self) -> Result<TableType> {
923
288
        let element_type = self.read_reference_type()?;
924
288
        let limits = self.read_limits()?;
925
926
288
        Ok(TableType {
927
288
            element_type,
928
288
            limits,
929
288
        })
930
288
    }
_RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderRShE15read_table_typeCs5HNiFFfDLPG_6decode
Line
Count
Source
922
288
    fn read_table_type(&mut self) -> Result<TableType> {
923
288
        let element_type = self.read_reference_type()?;
924
288
        let limits = self.read_limits()?;
925
926
288
        Ok(TableType {
927
288
            element_type,
928
288
            limits,
929
288
        })
930
288
    }
Unexecuted instantiation: _RNvMNtNtCsatfCxygFw5y_11wasm_parser7decoder7decoderINtB2_7DecoderpE15read_table_typeB6_
931
}
/Users/hota1024/GitHub/hota1024/wasmicon/crates/wasm_parser/src/decoder/result.rs
Line
Count
Source (jump to first uncovered line)
1
use super::binary::section::SectionId;
2
3
0
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
4
pub enum DecodeError {
5
    #[error("invalid magic header")]
6
    InvalidMagicHeader,
7
    #[error("invalid version")]
8
    InvalidVersion,
9
    #[error("invalid section id: {0:?}")]
10
    InvalidSectionId(SectionId),
11
    #[error("invalid reference type")]
12
    InvalidRefType,
13
    #[error("invalid table instruction id")]
14
    InvalidTableInstructionId,
15
    #[error("invalid sub instruction id: {0:#x}")]
16
    InvalidSubInstructionId(u32), // 0xFC xx
17
    #[error("unxpected EOF")]
18
    UnexpectedEof,
19
    #[error("expected {0}")]
20
    Expected(String),
21
22
    #[error("invalid block type")]
23
    InvalidBlockType,
24
25
    #[error("invalid type type")]
26
    InvalidTypeKind,
27
28
    #[error("invalid value type")]
29
    InvalidValueType(u8),
30
31
    #[error("invalid import description: 0x{0:#x}")]
32
    InvalidImportDescription(u8),
33
    #[error("invalid export description")]
34
    InvalidExportDescription,
35
36
    #[error("invalid global init expression")]
37
    InvalidGlobalInitExpr,
38
    #[error("invalid limits kind")]
39
    InvalidLimitsKind,
40
    #[error("invalid element kind")]
41
    InvalidElementKind,
42
43
    #[error("expected const expression")]
44
    ExpectedConstExpression,
45
    #[error("unsupported element prefix")]
46
    UnsupportedElementPrefix,
47
48
    #[error("unsupported data prefix")]
49
    UnsupportedDataPrefix(u32),
50
}
51
52
pub type Result<T> = anyhow::Result<T>;